Skip to content

Conversation

@slim-bean
Copy link
Collaborator

What this PR does / why we need it:
This PR fixes an issue where /loki/api/v1/query_range responses were incorrectly returning Content-Type: text/plain; charset=utf-8 instead of application/json; charset=UTF-8. This caused client-side errors due to unexpected MIME types. The fix explicitly sets the Content-Type header for JSON responses.

Which issue(s) this PR fixes:
Fixes #

Special notes for your reviewer:
The bug was introduced in December 2024 with the addition of Parquet support, where the Content-Type for JSON responses was inadvertently omitted. It became visible in the last 4 weeks due to recent changes wiring up the v2 engine handler into the query frontend, which increased traffic through the affected code path. The fix is a single line to set the header, consistent with other JSON response handling in the codebase.

Checklist

  • Reviewed the CONTRIBUTING.md guide (required)
  • Documentation added
  • Tests updated
  • Title matches the required conventional commits format, see here
    • Note that Promtail is considered to be feature complete, and future development for logs collection will be in Grafana Alloy. As such, feat PRs are unlikely to be accepted unless a case can be made for the feature actually being a bug fix to existing behavior.
  • Changes that require user attention or interaction to upgrade are documented in docs/sources/setup/upgrade/_index.md
  • If the change is deprecating or removing a configuration option, update the deprecated-config.yaml and deleted-config.yaml files respectively in the tools/deprecated-config-checker directory. Example PR

Slack Thread

Open in Cursor Open in Web

The serializeHTTPHandler was missing the Content-Type header for JSON
responses, causing clients to receive "text/plain; charset=utf-8" instead
of the expected "application/json; charset=UTF-8".

This bug was introduced in commit d0c11a6 (Dec 2024) when Parquet support
was added. The Parquet code path correctly sets the Content-Type header, but
the JSON code path (the default) was left without any Content-Type header.

The issue became visible in the last 4 weeks as the v2 engine router changes
(commits 72cb649 and d721511) made more query_range requests flow through
this code path.

This fix ensures JSON responses from /loki/api/v1/query_range and other query
endpoints have the correct Content-Type header set, matching the behavior in
other parts of the codebase (see codec.go lines 686, 1304).

Fixes: https://github.com/grafana/loki/issues/[issue-number]
@cursor
Copy link

cursor bot commented Nov 7, 2025

Cursor Agent can help with this pull request. Just @cursor in comments and I'll start working on changes in this branch.
Learn more about Cursor Agents

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@slim-bean
Copy link
Collaborator Author

@cursor can you check if any of the other query endpoints also need to be fixed?

@cursor
Copy link

cursor bot commented Nov 7, 2025

Great news! I've checked all query endpoints and the fix in serialize.go covers all query endpoints that were affected. Here's what I found:

✅ Fixed by this PR

All query endpoints flow through NewQuerierHTTPHandler() which wraps handlers with NewSerializeHTTPHandler() (the handler I just fixed):

  • /loki/api/v1/query_range - Range queries
  • /loki/api/v1/query - Instant queries
  • /loki/api/v1/labels - Label queries
  • /loki/api/v1/label/{name}/values - Label values
  • /loki/api/v1/series - Series queries
  • /loki/api/v1/index/stats - Index stats
  • /loki/api/v1/index/shards - Shards
  • /loki/api/v1/index/volume - Volume
  • /loki/api/v1/detected_fields - Detected fields
  • /loki/api/v1/patterns - Patterns
  • /loki/api/v1/detected_labels - Detected labels

Reference: pkg/querier/handler.go lines 139-141

✅ No Issues Found

Query Frontend Transport Handler (pkg/lokifrontend/frontend/transport/handler.go):

  • Uses roundTripper.RoundTrip() which returns complete HTTP responses
  • Copies headers from the roundtripper's response
  • Content-Type header comes from codec's EncodeResponse() which sets it correctly

Internal encoding functions:

  • prometheus.go - The encodeTo() method is only called by encode() which sets Content-Type: application/json
  • All other internal encoding paths use the codec's EncodeResponse() which properly sets headers

Conclusion

The single-line fix in serializeHTTPHandler.ServeHTTP() resolves the issue for all affected query endpoints. No additional changes needed! 🎉


Open in Cursor Open in Web

Learn more about Cursor Agents

@slim-bean slim-bean changed the title Investigate recent api response changes fix: Investigate recent api response changes Nov 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants