Skip to content

Incorrect header precedence behavior in firebase.json; sw.js no-cache overridden by later **/*.js rule #8917

@ouksal

Description

@ouksal

[REQUIRED] Environment info

firebase-tools:
v14.11.0
Platform:
macOS (M1)


[REQUIRED] Test case

Using the following firebase.json config:

"headers": [
  {
    "source": "/sw.js",
    "headers": [
      { "key": "Cache-Control", "value": "no-cache" }
    ]
  },
  {
    "source": "**/*.js",
    "headers": [
      { "key": "Cache-Control", "value": "public,max-age=31536000,immutable" }
    ]
  }
]

I expect the sw.js file to receive a Cache-Control: no-cache header.

[REQUIRED] Steps to reproduce

  1. Deploy the firebase.json above using firebase deploy.
  2. Visit https://<your-domain>/sw.js and check the response headers.
  3. Observe the Cache-Control header using browser DevTools or:
    curl -I https://<your-domain>/sw.js
  4. Now swap the order of the two rules in firebase.json, placing /sw.js after the **/*.js rule.
  5. Redeploy and repeat the check.

[REQUIRED] Expected behavior
The docs say header rules match top to bottom and the first match should apply.
Therefore, the /sw.js rule should match and override the more general **/*.js rule, regardless of order.

I expect:
Cache-Control: no-cache

[REQUIRED] Actual behavior
When the **/*.js rule appears after the /sw.js rule in firebase.json, the sw.js file receives the wildcard header:

Cache-Control: public,max-age=31536000,immutable

This causes service workers to be cached aggressively and prevents updates.

Only when I move the /sw.js rule after the **/*.js rule does the correct header apply.

This behavior contradicts the documentation and indicates that header rules are applied in order, and later rules override earlier ones, even if the first rule is a more specific match.

on sw.js regardless of where the rule appears in the array.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions