Skip to content

Fix/4973 json error responses#4977

Open
mehrdadbn9 wants to merge 1 commit intoprometheus:mainfrom
mehrdadbn9:fix/4973-json-error-responses
Open

Fix/4973 json error responses#4977
mehrdadbn9 wants to merge 1 commit intoprometheus:mainfrom
mehrdadbn9:fix/4973-json-error-responses

Conversation

@mehrdadbn9
Copy link

Fix #4973: Return JSON error responses instead of plain text

Problem

The Alertmanager API was returning error responses as plain text strings with incorrect Content-Type header:

  • Content-Type: application/json
  • Response Body: "bad matcher format: invalidfilter" (plain text string)
    This violates the JSON API specification as the response body is a quoted string, not a JSON object.

Solution

Updated the API to return proper JSON error responses with an error field:

  • Content-Type: application/json
  • Response Body: {"error":"bad matcher format: invalidfilter"} (valid JSON object)

Changes Made

  1. OpenAPI Spec (api/v2/openapi.yaml)

    • Changed all error response schemas from type: string to JSON objects with error field
    • Added proper error body types for all error responses (400, 404, 500)
  2. Swagger Code Generation

    • Regenerated REST API code with new error body types
    • Created proper error response structs:
      • GetAlertsBadRequestBody, GetAlertsInternalServerErrorBody
      • GetAlertGroupsBadRequestBody, GetAlertGroupsInternalServerErrorBody
      • GetSilencesBadRequestBody, GetSilencesInternalServerErrorBody
      • GetSilenceInternalServerErrorBody
      • DeleteSilenceInternalServerErrorBody
      • PostAlertsBadRequestBody, PostAlertsInternalServerErrorBody
      • PostSilencesBadRequestBody
  3. API Handlers (api/v2/api.go)

    • Updated all error handlers to create error body objects instead of passing raw strings
    • Fixed the following endpoints:
      • GET /api/v2/alerts
      • POST /api/v2/alerts
      • GET /api/v2/alerts/groups
      • GET /api/v2/silences
      • GET /api/v2/silences/:silence_id
      • DELETE /api/v2/silences/:silence_id
      • POST /api/v2/silences

Example

Before

$ curl -v "http://localhost:9093/api/v2/alerts/groups?filter=invalidfilter"
< HTTP/1.1 400 Bad Request
< Content-Type: application/json
"bad matcher format: invalidfilter"

@mehrdadbn9 mehrdadbn9 force-pushed the fix/4973-json-error-responses branch 2 times, most recently from 6d140f5 to fde3627 Compare February 8, 2026 12:28
@mehrdadbn9 mehrdadbn9 force-pushed the fix/4973-json-error-responses branch 4 times, most recently from f5e6e8f to 85a72e4 Compare February 9, 2026 02:40
@mehrdadbn9 mehrdadbn9 closed this Feb 9, 2026
@siavashs
Copy link
Contributor

siavashs commented Feb 9, 2026

Reopening the original PR after closing the new one the contributor had opened.
Please continue all updates and discussions here and avoid opening new PRs to fix the exact same issue.

Please see this guide on contributing to projects: https://docs.github.com/en/get-started/exploring-projects-on-github/contributing-to-open-source#working-with-project-maintainers

  • When feedback arrives about your pull request, respond promptly and professionally even if criticism feels harsh. Maintainers are typically focused on code quality.
  • If changes are requested for your pull request, don't open a new pull request to address the changes. Keeping the existing pull request open and making changes there helps prevent the maintainers from losing context.
  • If your pull request remains unaddressed for weeks, politely follow up with a comment requesting feedback. Do not directly mention the handles of maintainers. Maintainers often balance open source work with full-time responsibilities, and understanding their time constraints fosters better collaboration.
  • If your contribution does not get accepted, ask the maintainers for feedback so that you can have that context for the next time you want to make a contribution.

@siavashs siavashs reopened this Feb 9, 2026
@mehrdadbn9
Copy link
Author

mehrdadbn9 commented Feb 12, 2026

@siavashs Thank you for your valuable feedback on the previous attempts. I have addressed all the concerns:

Changes Made

1. Fixed Code Generation (Copyright Headers)

  • Now using make apiv2 to regenerate all API code with proper copyright headers
  • All generated files now include the Apache 2.0 license header

2. Consistent Messages in Logs and API

  • Updated all error handlers to use the same message variable in both logs and API responses
  • Example:
message := "Failed to compile receiver regex"
logger.Debug(message, "err", err)
eb := badRequestError(message, err)

3. Prometheus v1 Error Format (Addressing Breaking Change Concern)

To address the concern about breaking existing integrations, I've aligned the error format with Prometheus API v1:

{
  "status": "error",
  "errorType": "bad_data",
  "error": "Failed to parse matchers: bad matcher format: invalidfilter"
}

Why this is the right approach:

  • Aligns with Prometheus ecosystem conventions
  • Users familiar with Prometheus API will find this format intuitive
  • The errorType field (bad_data, internal) allows for programmatic error handling
  • This is technically a breaking change, but:
    • The current behavior is already inconsistent (claims JSON but returns a plain string)
    • Error responses are typically handled via HTTP status codes, not body parsing
    • The actual error message remains accessible in the error field

I would appreciate your feedback on whether this Prometheus v1 format approach is acceptable. If you prefer a different approach (e.g., adding versioning or Accept header negotiation), please let me know and I can implement that instead.

Thank you for your time and guidance!

@mehrdadbn9 mehrdadbn9 force-pushed the fix/4973-json-error-responses branch 3 times, most recently from 294c0e8 to c56a0f6 Compare February 12, 2026 16:25
@mehrdadbn9
Copy link
Author

mehrdadbn9 commented Feb 12, 2026

@siavashs I have rebased on the latest upstream/main and addressed all the feedback from the previous review:

Changes Made

1. Fixed Code Generation (Copyright Headers) ✅

  • Now using make apiv2 to regenerate all API code with proper copyright headers
  • All generated files include the Apache 2.0 license header

2. Consistent Messages in Logs and API ✅

  • Updated all error handlers to use the same message variable in both logs and API responses
  • Example:
message := "Failed to compile receiver regex"
logger.Debug(message, "err", err)
eb := badRequestError(message, err)

3. Prometheus v1 Error Format ✅

Aligned error format with Prometheus API v1:

{
  "status": "error",
  "errorType": "bad_data",
  "error": "Failed to parse matchers: bad matcher format: invalidfilter"
}

Rationale:

  • Aligns with Prometheus ecosystem conventions
  • Users familiar with Prometheus API will find this format intuitive
  • The errorType field (bad_data, internal) allows for programmatic error handling

4. Rebased on Latest Upstream ✅

  • Rebased on upstream/main to resolve all merge conflicts
  • All tests pass locally

I would appreciate your feedback on this approach. Thank you for your time and guidance!

- Update openapi.yaml error responses to use Prometheus v1 format:
  {status: 'error', errorType: string, error: string}
- Regenerate API code using make apiv2 with proper copyright headers
- Update all error handlers in api.go to use consistent messages
  in logs and API responses (per reviewer feedback)
- Add helper functions badRequestError() and internalError()

Example error response:
{
  "status": "error",
  "errorType": "bad_data",
  "error": "Failed to parse matchers: bad matcher format"
}

This aligns Alertmanager API with Prometheus API v1 error format
for ecosystem consistency.

Signed-off-by: mehrdadbn9 <mehrdabbiukian@gmail.com>
@mehrdadbn9 mehrdadbn9 force-pushed the fix/4973-json-error-responses branch from c56a0f6 to 6a9ab5d Compare February 12, 2026 20:24
@mehrdadbn9 mehrdadbn9 requested a review from siavashs February 13, 2026 09:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

API endpoint error returns error text with bad content type

2 participants