Skip to content

Avoid relying on HTTP reason-phrase for error handling (RFC 9112 compliance) #108

@prtrx

Description

@prtrx

Describe the bug
In lib/fog/proxmox/compute/models/servers.rb, error handling currently relies on the reason_phrase field from e.response.data which is not reliably propagated across HTTP intermediaries or proxies.

For example, when using Caddy as a reverse proxy in front of the Proxmox API, the reason-phrase from the upstream server (HTTP/1.1 500 Configuration file 'nodes/example-prox01/qemu-server/153157505.conf' does not exist) is replaced with the generic HTTP/1.1 500 Internal Server Error. This causes the plugin to fail, even though the body includes the correct error detail.

To Reproduce
Steps to reproduce the behavior:

  1. Put the API of a proxmox cluster behind a caddy running as reverse proxy.
  2. Have a VM running on any node other than the one the proxy talks to.
  3. Go to Infrastructure -> Compute Resources -> Virtual Machines -> the VM running on another node.
  4. The webinterface throws the following error: **ComputeResourcesVm not found** Please try to update your request

Expected behavior
Instead of parsing reason_phrase, inspect the response body where the actual API error message resides as "message" within the JSON. The response body looks like this:
{"message":"Configuration file 'nodes/example-prox01/qemu-server/153157505.conf' does not exist\n","data":null}

Screenshots
The http request made when talking directly to the API. Foreman will try through all servers until the configuration file is found.
Image
The http requests made when talking to the API via caddy. Foreman will give up after the first '500' reply.
Image
When it encounters the '500' it will throw a backtrace: caddy_requests.txt

Additional context
Per RFC 9112:

A client SHOULD ignore the reason-phrase content because it is not a reliable channel for information (it might be translated for a given locale, overwritten by intermediaries, or discarded when the message is forwarded via other versions of HTTP).

Source: https://datatracker.ietf.org/doc/html/rfc9112#section-4-8

This issue was encountered in a production setup where Foreman uses this plugin to manage VMs on a Proxmox cluster, with a Caddy reverse proxy placed in front of the Proxmox API. Caddy internally uses Go's net/http standard library, which deliberately discards or replaces the HTTP reason-phrase with a generic message (e.g., "Internal Server Error"). This behavior is not configurable and aligns with modern HTTP standards.

As a result, the plugin’s check for a specific reason_phrase (such as "does not exist") fails, even though the Proxmox API is correctly returning a 500 status and a detailed error message in the JSON body. Parsing the structured body instead resolves this.

Thanks for your work and kind regards.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions