워드프레스 한글 URL 리디렉션이 404 나는 이유: 퍼센트 인코딩 대소문자 문제
티스토리에서 워드프레스로 옮긴 뒤 글 주소를 한글 슬러그에서 영문 슬러그로 한꺼번에 바꿨다. 예전 주소로 들어오는 방문자와 구글이 새 주소를 찾아갈 수 있도록 리디렉션 규칙도 200개 넘게 만들어 두었다. 그런데 몇 달 뒤 구글 서치콘솔을 열어 보니 “찾을 수 없음(404)”과 “크롤링됨 – 현재 색인이 생성되지 않음”이 잔뜩 쌓여 있었다.
규칙은 분명히 있는데 왜 404가 날까. 원인은 생각보다 사소한 곳에 있었다. 한글 주소를 표현하는 퍼센트 인코딩의 대문자와 소문자 차이였다.
증상: 규칙은 있는데 404가 난다
리디렉션 플러그인 관리 화면에는 이런 규칙이 멀쩡히 등록되어 있었다.
/cafe24-호스팅을-떠나며/→/leaving-cafe24-hosting/
그런데 브라우저 주소창에 예전 주소를 넣으면 404 페이지가 떴다. 서치콘솔에서 구글이 알고 있는 옛 주소 156개를 뽑아 하나씩 확인해 보니, 108개가 그대로 404였고 30개는 리디렉션을 거친 뒤 결국 404로 끝났다. 정상적으로 새 글에 도착하는 주소는 손에 꼽을 정도였다.


원인 찾기: 같은 주소를 두 가지로 요청해 보기
한글이 들어간 주소는 실제로 서버에 보낼 때 퍼센트 인코딩으로 바뀐다. “호”는 %ED%98%B8처럼 바이트마다 %와 16진수 두 자리로 표현된다. 여기서 16진수의 알파벳 부분은 대문자로 써도, 소문자로 써도 같은 뜻이다. 표준(RFC 3986)에서도 둘을 같은 값으로 본다.
그래서 같은 주소를 소문자 인코딩과 대문자 인코딩으로 각각 요청해 봤다.
# 소문자 인코딩
curl -s -o /dev/null -w "%{http_code} %{redirect_url}\n" \
"https://itinfo.it.kr/cafe24-%ed%98%b8%ec%8a%a4%ed%8c%85%ec%9d%84-%eb%96%a0%eb%82%98%eb%a9%b0/"
# 대문자 인코딩
curl -s -o /dev/null -w "%{http_code} %{redirect_url}\n" \
"https://itinfo.it.kr/cafe24-%ED%98%B8%EC%8A%A4%ED%8C%85%EC%9D%84-%EB%96%A0%EB%82%98%EB%A9%B0/"
정리하기 전 결과는 이랬다.
301 https://itinfo.it.kr/leaving-cafe24-hosting/
404
같은 주소인데 소문자로 보내면 301로 새 글에 가고, 대문자로 보내면 404가 났다. 문제는 브라우저와 구글봇이 한글 주소를 보낼 때 대문자 인코딩을 쓴다는 점이다. 결국 규칙은 있지만 실제 방문자와 구글봇의 요청에는 한 번도 맞지 않았던 셈이다.
왜 소문자로 저장되었을까
워드프레스는 한글 슬러그를 데이터베이스에 저장할 때 퍼센트 인코딩을 소문자로 저장한다. 글 편집 화면에서는 한글로 보이지만, 내부적으로는 cafe24-%ed%98%b8... 같은 형태다.
필자가 쓰던 리디렉션 플러그인은 슬러그를 일괄 변경하는 기능으로 규칙을 만들었는데, 이때 워드프레스에 저장된 소문자 인코딩을 그대로 규칙의 출발 주소로 넣었다. 그리고 요청이 들어오면 주소를 문자열 그대로 비교하는 것으로 보였다. 소문자 규칙과 대문자 요청이 끝내 맞지 않은 이유다.
- 워드프레스가 한글 슬러그를 소문자 인코딩으로 저장한다
- 플러그인이 그 값을 그대로 리디렉션 규칙으로 저장한다
- 브라우저와 구글봇은 대문자 인코딩으로 요청한다
- 플러그인이 둘을 다른 주소로 보고 규칙을 건너뛴다
- 워드프레스는 해당 글을 찾지 못해 404를 낸다
내 사이트도 같은 문제인지 확인하는 법
- 리디렉션 플러그인에 등록된 옛 주소 가운데 한글이 들어간 것을 하나 고른다.
- 브라우저 주소창에 그 주소를 그대로 붙여 넣어 본다. 404가 뜨면 의심해 볼 만하다.
- 위의 curl 명령처럼 소문자 인코딩과 대문자 인코딩으로 각각 요청해 본다. 소문자만 301이 나온다면 이 문제다.
- 서치콘솔의 페이지 색인 생성 보고서에서 “찾을 수 없음(404)”과 “리디렉션 오류” 목록에 한글 주소가 많은지 본다.
해결: 디코딩해서 비교하는 리디렉션 기능으로 옮기기
해결 방법은 주소를 한글로 되돌려(디코딩해) 비교하는 리디렉션 기능을 쓰는 것이다. 필자는 이미 쓰고 있던 All in One SEO(AIOSEO)의 리디렉션 관리 기능을 시험해 봤다. 같은 규칙을 AIOSEO에 하나 등록하고 대문자 인코딩으로 요청하니 정상적으로 301이 나왔다. 그래서 리디렉션을 AIOSEO 하나로 합치기로 했다.

1. 리디렉션 체인 없애기
규칙을 모아 보니 “숫자 주소 → 한글 주소 → 영문 주소”처럼 두세 번을 거치는 규칙이 많았다. 티스토리 시절 숫자 주소(/213)가 한글 주소로 가고, 그 한글 주소가 다시 영문 주소로 가는 식이다. 이런 연쇄 리디렉션은 구글이 끝까지 따라가지 않을 수도 있고, 중간 하나만 깨져도 전체가 404가 된다.
그래서 규칙마다 최종 목적지를 계산해서, 모든 옛 주소가 한 번의 301로 바로 현재 글에 도착하도록 목적지를 고쳤다.
2. 기존 규칙 옮기기
- 기존 플러그인 규칙 229개와 AIOSEO에 있던 규칙을 합쳐 최종 목적지를 계산했다
- AIOSEO에 228개를 새로 만들고, 옛 한글 주소를 가리키던 기존 규칙 19개의 목적지를 고쳤다
- 모든 규칙을 옮긴 뒤 기존 플러그인은 삭제하지 않고 비활성화만 했다. 며칠 지켜보고 문제가 없으면 삭제할 생각이다
3. 본문 속 옛 링크도 함께 바꾸기
리디렉션이 동작하더라도 글 본문 안에 옛 한글 주소로 걸린 링크가 남아 있으면, 클릭할 때마다 한 번씩 돌아서 간다. 글 23개에 남아 있던 옛 주소 65곳을 현재 주소로 바꿨다. 일반 링크뿐 아니라 링크 미리보기 카드와 이미지 링크 안에 저장된 주소까지 찾아야 해서, 글 본문 원문(HTML) 기준으로 검색했다.
결과 확인
정리를 마치고 같은 curl 명령을 다시 보내 보니, 이제는 대문자로 요청해도 301로 새 글에 도착했다.

서치콘솔에서 뽑은 옛 주소 156개도 구글봇과 같은 사용자 에이전트로 다시 요청해 봤다.
| 구분 | 정리 전 | 정리 후 |
|---|---|---|
| 한 번의 301로 글에 도착 | 거의 없음 | 146개 |
| 404 | 108개 | 6개 (이미 지운 글) |
| 301을 거쳐 404 | 30개 | 0개 |
| 두 번 이상 거치는 리디렉션 | 9개 | 0개 |
남은 404 6개는 예전에 지운 글이라 연결할 대상이 없는 주소다. 이런 주소는 404로 두면 구글이 알아서 목록에서 뺀다. 서치콘솔 보고서 숫자는 구글이 다시 크롤링해야 바뀌기 때문에, 고친 직후에는 그대로 보인다. 유효성 검사를 시작해 두고 몇 주 지켜보면 된다.
정리: 한글 슬러그를 바꿀 때 기억할 것
- 한글 주소는 퍼센트 인코딩의 대소문자가 섞일 수 있다. 리디렉션 기능이 디코딩해서 비교하는지 꼭 확인하자
- 규칙을 만든 뒤에는 브라우저 주소창에 옛 주소를 직접 넣어 보거나, curl로 대문자 인코딩 요청을 보내 실제로 301이 나오는지 시험하자
- 리디렉션은 한 번에 최종 주소로 가게 만들자. 체인은 언젠가 깨진다
- 리디렉션 플러그인은 하나로 통일하는 편이 관리하기 쉽다
- 무엇보다 슬러그는 자주 바꾸지 않는 것이 가장 좋다. 바꿀 때마다 구글은 그 글을 처음부터 다시 평가한다
필자는 이 문제를 서치콘솔의 404 목록을 보고서야 알았다. 규칙이 등록되어 있다는 것만으로 안심하지 말고, 실제 요청으로 한 번은 확인해 보길 권한다. 워드프레스를 운영하며 겪은 다른 문제는 워드프레스 업데이트 후 치명적인 오류 해결기에 정리해 두었다.
첫 댓글을 남겨보세요