키를 분명히 새로 받았는데 인증만 계속 실패할 때, 어디를 봐야 하는지 알아보는 글입니다.
메일 발송 계정 정보를 갱신하고 나서 발송이 전부 막혔습니다. 로그에는 535 하나만 반복해서 찍혔습니다.
정확히는 javax.mail.AuthenticationFailedException: 535 Authentication Credentials Invalid 였습니다.
키는 방금 발급받은 것이고 오타도 없었습니다. 그런데도 서버는 계속 자격증명이 틀렸다고 답했습니다.
원인은 단순했는데, 콘솔에서 받은 값을 그대로 쓰면 안 되는 자리가 하나 있었습니다.
- 535는 자격증명이 틀렸다는 뜻이지 권한이나 네트워크 문제가 아니다
- SMTP 비밀번호는 IAM 시크릿 키가 아니다. 별도 변환이 필요하다
- 사용자명은 AKIA...로 시작해서 IAM 키와 똑같이 생겼다
- 변환 결과는 리전마다 다르다
- 갱신할 때 비밀번호만 갈아끼우면 또 막힌다
1. 증상은 한 줄뿐입니다
발송을 시도하면 인증 단계에서 바로 끊깁니다. 스택을 아무리 봐도 더 나올 게 없습니다.
535 Authentication Credentials Invalid 는 SMTP 표준에서 인증 실패를 뜻합니다. 서버까지는 잘 갔고, 연결도 됐고, TLS도 붙었는데 아이디와 비밀번호만 거절당한 상태입니다.
그래서 방화벽이나 포트를 뒤지는 건 대부분 헛수고입니다. 거기까지 갔으니 응답을 받은 것이니까요.

2. 원인은 비밀번호 자리에 있습니다
콘솔에서 액세스 키를 만들면 두 값이 나옵니다. 액세스 키 ID와 시크릿 액세스 키입니다.
여기서 착각이 생깁니다. 사용자명 자리에 액세스 키 ID를 넣는 건 맞는데, 비밀번호 자리에 시크릿 키를 그대로 넣으면 안 됩니다.
SMTP 비밀번호는 시크릿 키를 정해진 방식으로 변환한 별도의 문자열입니다. 원본을 넣으면 형식은 그럴듯한데 서버는 모르는 값이라 거절합니다.
- 사용자명 = 액세스 키 ID (AKIA로 시작, 그대로 사용)
- 비밀번호 = 시크릿 키를 변환한 값 (원본 아님)
사용자명이 그대로 들어가니까 절반은 맞습니다. 그래서 더 헷갈립니다. 키를 잘못 받았나 싶어 다시 발급받아도 같은 자리에서 막힙니다.
3. 변환은 직접 할 수 있습니다
가장 편한 방법은 콘솔에서 SMTP 전용 자격증명 생성 메뉴를 쓰는 것입니다. 그러면 변환이 끝난 비밀번호를 바로 내려줍니다.
이미 시크릿 키만 가지고 있다면 직접 만들어도 됩니다. 서명 키를 단계별로 파생시킨 뒤 버전 바이트를 붙여 인코딩하는 방식입니다.

여기서 리전이 인자로 들어가는 게 핵심입니다. 같은 시크릿 키라도 리전이 다르면 결과 문자열이 달라집니다.
4. 리전이 어긋나면 똑같이 535입니다
접속하는 주소와 자격증명을 만든 리전은 같아야 합니다.
서울 리전 주소로 접속하면서 버지니아 리전 기준으로 만든 비밀번호를 쓰면, 값 자체는 정상인데 서버가 못 알아봅니다. 증상은 똑같이 535라서 구분이 안 됩니다.
- 접속 주소의 리전과 자격증명 리전을 눈으로 맞춰 볼 것
- 주소를 바꿨으면 비밀번호도 다시 만들어야 한다
5. 갱신할 때 비밀번호만 바꾸면 또 막힙니다
주기적으로 키를 교체하는 곳이라면 이 함정이 한 번은 옵니다.
새 키를 받으면 사용자명도 같이 바뀝니다. 그런데 설정 파일에서 비밀번호 줄만 눈에 띄다 보니, 사용자명은 예전 값 그대로 두고 비밀번호만 갈아끼우는 일이 생깁니다.
그러면 예전 사용자명과 새 비밀번호가 짝이 안 맞아서 또 535입니다.

갱신 후에는 두 값을 나란히 놓고 확인하는 게 확실합니다. 특히 여러 서비스가 같은 설정을 공유하고 있으면 한 곳만 남아 있어도 그쪽에서만 실패합니다.
6. 허용 IP가 걸려 있으면 값이 맞아도 거절됩니다
여기까지 다 맞췄는데도 막힌다면, 자격증명에 접속 IP 조건이 붙어 있는지 봐야 합니다.
콘솔에 허용 IP 목록 같은 화면이 따로 있는 건 아닙니다. 자격증명에 연결된 권한 정책에 조건으로 들어갑니다.

이 목록에 없는 곳에서 접속하면 자격증명이 아무리 정확해도 인증 단계에서 거절됩니다. 그리고 돌아오는 응답은 똑같이 535라서, 값이 틀린 건지 위치가 틀린 건지 구분이 안 됩니다.
- 서버를 옮겼다면 새 서버가 나가는 IP를 목록에 넣어야 한다
- 회선이나 NAT가 바뀌었다면 예전 IP가 그대로 남아 있을 수 있다
- 목록을 고치고 나면 바로 반영되므로 재발급은 필요 없다
그래서 값이 확실한데 계속 막힌다면, 키를 다시 만들기 전에 나가는 IP부터 확인하는 게 빠릅니다.
함정이 하나 더 있습니다. 사설망 안에서 전용 통로를 거쳐 나가는 구성이라면, 출발지 IP라는 정보 자체가 잡히지 않습니다.
그 경우 IP 조건은 아무도 만족시킬 수 없어서 모두가 막힙니다. 이때는 IP 대신 통로 자체를 조건으로 거는 방식으로 바꿔야 합니다.
7. 그래도 안 되면 볼 곳
여기까지 맞췄는데도 막힌다면 남은 후보는 좁습니다.
- 권한 - 발송 권한이 정책에 들어 있는지
- 포트와 암호화 - 587은 STARTTLS, 465는 처음부터 TLS. 섞이면 인증 전에 끊긴다
- 디버그 로그 - 메일 라이브러리의 디버그 옵션을 켜면 어느 단계에서 끊겼는지 한 줄로 나온다
디버그를 켜면 인증 실패인지 연결 실패인지가 바로 갈립니다. 추측하기 전에 켜는 게 빠릅니다.
8. 정리
535를 보면 키를 다시 발급받고 싶어지는데, 대부분은 키가 아니라 넣는 자리의 문제입니다.
정리하면 이렇습니다.
- 535 = 자격증명 불일치. 네트워크나 권한이 아니다
- 비밀번호는 시크릿 키가 아니라 변환한 값
- 사용자명은 액세스 키 ID 그대로
- 변환 결과는 리전에 묶여 있다
- 갱신할 때는 사용자명과 비밀번호를 한 쌍으로 교체
- 허용 IP 조건이 붙어 있으면 값이 맞아도 거절된다
한 번 알고 나면 다시는 안 걸리는데, 모르는 상태에서는 키만 계속 다시 발급받게 되는 함정입니다. 비밀번호 자리를 먼저 의심해 보시면 시간을 많이 아낍니다.
여기까지 AWS SES의 535 인증 실패에 대해서 작성해봤습니다. 여기까지 읽어주셔서 감사합니다!
'일상' 카테고리의 다른 글
| AES 암호화 결과가 매번 다를 때 (암호문 앞에 붙는 랜덤 IV) (0) | 2026.09.09 |
|---|---|
| 3.3% 떼고 받았는데 5월에 또 신고하라고 할 때 (원천징수는 세금이 아니라 선납) (0) | 2026.09.09 |
| ssh-keygen 한 번에 개인키를 날렸을 때 (덮어쓰기 함정과 복구 경로) (0) | 2026.08.30 |
| python-pptx로 투명도와 그라데이션 넣기 (안 먹는 속성 대신 XML 직접 쓰기) (0) | 2026.08.30 |
| 자바 8에서 AES-256이 갑자기 안 될 때 (JCE 정책 파일과 8u161 경계) (0) | 2026.08.29 |