n8n 워크플로우 자동화

n8n Slack invalid_auth 케이스 스터디: 토큰이 맞아도 실패하는 이유

2026. 07. 13.
n8nSlackDebuggingCase Study

n8n 워크플로우를 짜다 하루를 태운 사례를 정리한다.

증상은 단순했다.

- GitHub PR merge → Claude → Notion + Slack 파이프라인
- Notion 은 성공, Slack 만 계속 invalid_auth 실패
- Slack Bot Token 은 방금 재발급 → "키값은 맞아"

이 상황에서 원인을 찾아간 순서를, 재현 가능한 형태로 남긴다. 같은 증상을 만나면 이 순서대로 좁혀 가면 30분 안에 잡을 수 있다.


첫 번째 착각: "토큰이 맞으니 API 문제겠지"

Slack API 가 invalid_auth 를 뱉는다고 하면 반사적으로 토큰을 의심한다. 그리고 토큰을 재발급받는다. 그런데 여전히 invalid_auth.

여기서 다들 "왜?"라며 삽질을 시작한다.

원인의 가짓수는 사실 유한하다.

1. Slack Bot Token 자체가 유효하지 않음 (rotate, revoke, uninstall)
2. 필요한 스코프가 없음 (chat:write 등)
3. HTTP 요청 방식이 잘못됨 (Content-Type 누락 등)
4. n8n 이 참조하는 credential 이 다른 것 (배선 문제)
5. Header 값에 Bearer prefix 누락 or 공백/개행 포함

이걸 위에서 아래로 하나씩 잘라내면 된다.


Step 1. 토큰 자체가 살아있는지 확인 — auth.test

n8n 밖으로 나와서 순수 curl 로 확인한다. 가장 스코프가 낮은 auth.test 부터.

curl -X POST https://slack.com/api/auth.test \
  -H "Authorization: Bearer xoxb-..."

응답 해석표:

{"ok":true, ...}                         → 토큰 살아있음, 다음 스텝
{"ok":false,"error":"invalid_auth"}     → 토큰 자체 문제, rotate 필요
{"ok":false,"error":"token_revoked"}    → workspace 재설치 필요
{"ok":false,"error":"account_inactive"} → workspace 자체 문제

내 케이스는 ok:true 였다. 즉 토큰은 완전히 유효하다는 게 확정. 여기서 원인 후보 1번은 제거된다.


Step 2. 실제 호출 API 로 확인 — chat.postMessage

auth.test 는 스코프가 없어도 통과한다. n8n 이 실제 호출하는 chat.postMessagechat:write 스코프와 채널 접근이 있어야 통과한다.

curl -X POST https://slack.com/api/chat.postMessage \
  -H "Authorization: Bearer xoxb-..." \
  -H "Content-Type: application/json; charset=utf-8" \
  -d '{"channel":"#dev-log","text":"curl test"}'

응답 해석표:

{"ok":true,...}                                  → Slack 쪽 100% 정상
{"ok":false,"error":"not_in_channel"}            → 봇을 채널에 /invite 필요
{"ok":false,"error":"missing_scope","needed":"chat:write"}
                                                 → 스코프 추가 + 앱 재설치
{"ok":false,"error":"channel_not_found"}         → 채널 ID 로 교체
{"ok":false,"error":"invalid_auth"}              → 여기서 나오면 스코프 문제

내 케이스는 이것도 ok:true 였다. 실제 채널에 "curl test" 메시지가 도착했다.

이 시점에서 Slack 쪽은 100% 정상이라는 게 증명됐다. 그러면 원인은 오직 하나로 좁혀진다.

n8n 노드가 이 정상 토큰을 그대로 못 쓰고 있다.


Step 3. n8n credential 배선을 의심한다

n8n Credentials 목록을 다시 봤다.

- Slack (Header Auth)        ← 방금 만든 것
- Header Auth account        ← 이름부터 수상함 (n8n 기본 이름)
- Anthropic (Header Auth)
- GitHub PAT credential
- GitHub account

"Header Auth account" 라는 기본 이름 credential 이 남아 있었다. 이건 처음 노드를 만들 때 자동 생성된 이후 그대로 방치된 것.

여기서 가설이 서게 된다.

Slack: notify 노드가 Slack (Header Auth) 가 아니라 옛날의 Header Auth account 를 참조하고 있는 게 아닐까?


Step 4. 노드의 credential 참조를 강제 재바인딩

n8n 은 노드가 credential 을 이름이 아니라 UUID 로 참조한다. credential 을 삭제/재생성하면 UUID 가 바뀌고, 노드는 옛날 UUID 를 그대로 붙들고 있는다.

해결 절차:

1. Slack: notify 노드 더블클릭
2. Credential for Header Auth 드롭다운 열기
   → 여기서 지금 뭐가 선택돼 있는지 눈으로 확인 (범인 확인)
3. 아무 다른 credential 하나 선택 → 다시 원래 원하는 것 선택
4. 노드 Save → 워크플로우 Save
5. 노드 우측 상단 Execute node

이 순간 파이프라인이 통과했다. 원인 확정.


회고: 이 삽질에서 얻은 교훈 3가지

1. "토큰이 맞다"는 곧바로 믿지 않는다

토큰이 물리적으로 맞아도 어디에 어떻게 저장돼 있는지가 다를 수 있다. n8n credential 필드에 저장된 값과 curl 에 붙여넣은 값이 정말 같은지는 직접 확인 전엔 모른다. (Value 필드가 마스킹돼 있어서 눈으로 못 봄)

2. 문제를 두 개로 자른다 — "API 는 되는가" vs "내 도구는 되는가"

Slack invalid_auth 를 만나면 곧바로 두 갈래로 자른다.

- curl 로도 실패한다   → Slack 자체 문제 (스코프, 채널, 토큰)
- curl 은 되는데 도구만 실패 → 내 도구의 배선 문제 (n8n credential 등)

curl 한 줄로 5분이면 두 영역을 분리할 수 있다. 이걸 안 하고 도구 UI 안에서만 뒤지면 하루가 간다.

3. UI 도구의 "기본 이름" credential 은 즉시 이름을 붙인다

Header Auth account, HTTP Request account 같은 자동 생성 이름은 반드시 그 자리에서 Slack (Header Auth), Notion (Header Auth) 처럼 용도 붙여서 리네임한다. 안 그러면 나중에 어느 노드가 뭘 참조하는지 알 수 없고, credential 을 재생성할 때마다 배선이 꼬인다.


요약: invalid_auth 진단 체크리스트

3분 안에 원인 좁히는 순서.

[1] curl -X POST https://slack.com/api/auth.test -H "Authorization: Bearer $TOKEN"
    → ok:false 면 토큰 문제, rotate

[2] curl -X POST https://slack.com/api/chat.postMessage \
       -H "Authorization: Bearer $TOKEN" \
       -H "Content-Type: application/json; charset=utf-8" \
       -d '{"channel":"#test","text":"ok"}'
    → not_in_channel   : /invite 필요
    → missing_scope    : 앱 스코프 추가 + 재설치
    → channel_not_found: 채널 ID 로 교체

[3] 위 둘 다 ok:true 인데 n8n 만 실패
    → 노드의 credential 재선택 후 Save → Execute node

Slack invalid_auth 뿐 아니라 Notion / OpenAI / 다른 SaaS 도 로직은 같다. "API 는 되는가 → 내 도구는 되는가" 두 계층으로 잘라서 좁혀 들어가는 게 핵심.