HTTP Headers Go Lowercase and That’s a Good Thing
Storyblok is the first headless CMS that works for developers & marketers alike.
The internet runs on standards
The internet runs on standardized protocols that have been written, debated, and refined over decades. These standards, publicly documented in RFCs (Request for Comments), describe exactly how every communication layer should behave.
- TCP/IP: defines how computers split files into small packets and send them across networks.
- HTTP: describes how browsers and servers exchange requests and responses.
- HTML: defines how web pages are structured and displayed.
- DNS: translates human-readable names like
storyblok.cominto IP addresses.
These specifications allow independent systems, written in different languages, to communicate seamlessly, improving interoperability among diverse systems.
Sometimes, following them more precisely exposes rules that have been there all along.
The hidden rule: header names are case-insensitive
If you’ve ever inspected HTTP traffic, you’ve seen headers like:
Content-Type: application/json
X-Request-ID: 12345
Cache-Control: no-cache Some may not realize that header names have never been case-sensitive. Instead, the HTTP specification has always required that field names be treated as case-insensitive. This means that Content-Type, content-type, and CONTENT-TYPE all represent the same header.
Most libraries already normalize them automatically, which is why you’ve likely never noticed this rule in action.
When HTTP/2 was introduced, it preserved the case-insensitivity rule but added a new requirement: all header names must be transmitted in lowercase.
HTTP/1.1 | HTTP/2 |
|---|---|
|
|
|
|
Clients and servers still treat header names as case-insensitive, but the canonical form sent over the network is now lowercase.
Storyblok’s API and Rack 3
The Storyblok API is primarily built with Ruby. Rack is the de facto standard interface between web servers and web applications. The Ruby ecosystem adopted the new behavior of HTTP/2 headers in Rack v3, which normalizes all response header fields to lowercase before sending them.
When we recently upgraded Storyblok's backend to Rack 3, everything continued to work seamlessly: tests passed, integrations behaved normally, and monitoring tools reported as usual. That’s because our entire stack (Rails, SDKs, and HTTP clients) was already standards-compliant, comparing headers precisely as the RFCs specify.
The migration was seamless, which is the best possible outcome.
Check your implementation
Most HTTP client libraries already handle header names case-insensitively. For example:
requestsin PythonaxiosorFetchin JavaScriptFaradayorNet::HTTPin Rubynet/httpin GoHttpClientorOkHttpin JavaSymfony HTTP Clientfor PHP
If your code uses any of these, it will continue to work without any changes.
Issues may occur only if your code assumes that header names are case-sensitive, for example, when using raw hash or dictionary lookups.
To check if your code is compatible, run the following snippet (depending on your stack):
# Check how your client or implementation handles different cases:
# Both requests should return the same value.
puts headers["content-type"]
puts headers["Content-Type"]
# Otherwise, read both versions to guarantee compatibility with the upcoming change.
value = headers["content-type"] || headers["Content-Type"] If both requests return the same value, your implementation already follows the HTTP/2 specification.
If only one does, update your code to support both variants until your HTTP client automatically normalizes headers.
What to expect during the rollout
- When? We’ll roll out lowercase header names across all Storyblok API responses on 26.11.2025.
- What changes? All header names will be transmitted in lowercase, following the HTTP/2 specification.
- Impact? None for compliant clients and frameworks. Everything should continue to work as before.
- Who needs to act? Only those who manually read or compare headers using case-sensitive keys.
- How to avoid issues? Check your implementation now. If you find case-sensitive logic, read both header variants as shown in the snippet above.
Takeaways
The web’s reliability depends on rules that most of us never see.
HTTP headers' case sensitivity is one of those quiet rules: invisible when followed, disruptive when ignored.
By aligning our API with the HTTP/2 specification, we’re not changing behavior; we’re confirming it.
If your tools and libraries follow the same standards, you won't notice the change—everything will continue to work exactly as before.
Verify your API integrations before 26.11.2025 to avoid any unexpected behavior.