dify - 💡(How to fix) Fix [Bug] Authorization header prefix ("Bearer "/"Basic ") accumulates on repeated Custom Tool calls due to credentials mutation

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Root Cause

When a Custom Tool is configured with API Key Header authentication and prefix Bearer (or Basic), the Authorization header value gets a new Bearer (or Basic ) prefix prepended on every invocation, because runtime.credentials["api_key_value"] is mutated in-place and the runtime object is shared across calls.

Code Example

[WARNING] 403 token-mismatch  got=Bearer...ae(len=71)  expected_len=64
[WARNING] 403 token-mismatch  got=Bearer...ae(len=78)  expected_len=64
[WARNING] 403 token-mismatch  got=Bearer...ae(len=85)  expected_len=64

---

Authorization: Bearer <token>
RAW_BUFFERClick to expand / collapse

Self Checks

  • I have read the Contributing Guide and Language Policy.
  • This is only for bug report, if you would like to ask a question, please head to Discussions.
  • I have searched for existing issues search for existing issues, including closed ones.
  • I confirm that I am using English to submit this report, otherwise it will be closed.
  • 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
  • Please do not modify this template :) and fill in all the required fields.

Dify version

1.13.13

Cloud or Self Hosted

Self Hosted (Docker)

Steps to reproduce

When a Custom Tool is configured with API Key Header authentication and prefix Bearer (or Basic), the Authorization header value gets a new Bearer (or Basic ) prefix prepended on every invocation, because runtime.credentials["api_key_value"] is mutated in-place and the runtime object is shared across calls.

As a result, repeated calls (Agent multi-step, parallel calls, retries) send increasingly malformed headers and fail with 401/403.

Reproduce

  1. Create a Custom Tool with the following authentication settings:
    • Auth type: API Key
    • Header name: Authorization
    • Prefix: Bearer
    • Value: <my_token> (e.g. a 64-char string)
  2. Build a simple Agent / Workflow that calls this tool 3 times in a row (e.g. with different query parameters).
  3. Inspect the Authorization header received by the upstream API.

Observed headers

CallAuthorization header valueLength
1Bearer <token>71
2Bearer Bearer <token>78
3Bearer Bearer Bearer <token>85

Each subsequent call adds another Bearer (7 chars) to the header.

Real log from upstream API

[WARNING] 403 token-mismatch  got=Bearer...ae(len=71)  expected_len=64
[WARNING] 403 token-mismatch  got=Bearer...ae(len=78)  expected_len=64
[WARNING] 403 token-mismatch  got=Bearer...ae(len=85)  expected_len=64

71 - 64 = 7 → 1× "Bearer " 78 - 64 = 14 → 2× "Bearer " 85 - 64 = 21 → 3× "Bearer "


✔️ Expected Behavior

Every call should send exactly:

Authorization: Bearer <token>

regardless of how many times the tool is invoked.


❌ Actual Behavior

The Bearer (or Basic ) prefix is prepended cumulatively on every invocation, because the credential dictionary held by self.runtime is mutated in-place.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING