ServiceCallout Policy Incorrectly Adds "authority" Header to HTTP Response

Environment

Product: Apigee Edge for Private Cloud

Version: 4.53.00.00

Component: ServiceCallout Policy + AssignMessage Policy

Severity: Medium (HTTP Protocol Violation)

Summary

When using ServiceCallout policy to call a backend target, Apigee incorrectly adds an “authority” response header to the HTTP response returned to clients. This violates HTTP specifications, as “authority” (or :authority in HTTP/2) is strictly a request header and should never appear in responses.

Issue Description

We have observed that Apigee adds an “authority” header to HTTP responses when using the ServiceCallout policy in combination with AssignMessage policy to copy response data. This occurs even though:

The backend target service does NOT return any “authority” or “Host” header in its response (verified with direct curl testing)

The AssignMessage policy explicitly copies only specific headers (Content-Type in our case)

The backend developers confirmed their code does not set any such headers

Steps to Reproduce

1. Proxy Configuration

Create an API proxy with a ServiceCallout policy:

<Request variable="customRequest"/>

<Response>customResponse</Response>

<HTTPTargetConnection>

    <URL>http://notfound</URL>

</HTTPTargetConnection>

2. Request Creation Policy

Create request using AssignMessage:

<Copy source="request">

    <Verb>true</Verb>

    <Headers>

        <Header name="Accept"/>

    </Headers>

    <QueryParams>true</QueryParams>

    <Payload>true</Payload>

</Copy>

<AssignTo createNew="true" transport="http" type="request">customRequest</AssignTo>

3. Response Handling Policy

Copy response back to client:

<Copy source="customResponse">

    <StatusCode>true</StatusCode>

    <ReasonPhrase>true</ReasonPhrase>

    <Payload>true</Payload>

    <Headers>

        <Header name="Content-Type"/>

    </Headers>

</Copy>

<AssignTo createNew="false" transport="http" type="response"/>

4. Call the API

Make an HTTP/2 request to the Apigee proxy endpoint.

Expected Behavior

The response to the client should contain ONLY the headers returned by the backend target service, plus any explicitly added by Apigee policies. The “authority” header should NOT be present in the response.

Actual Behavior

The response contains an “authority” header that was never returned by the backend service. When traced using Apigee’s trace tool, the “authority” header appears in the response headers returned to the client.

Verification

We verified the backend behavior by calling it directly:

curl --http2 -I -v https://backend-service.example.com/api/endpoint

Result: Backend response does NOT contain any “authority” or “Host” header (see backend response headers below).

Backend Response Headers (Direct Call):

HTTP/2 200

content-type: application/json; charset=utf-8

date: Tue, 06 Jan 2026 07:22:36 GMT

content-length: 467

strict-transport-security: max-age=31536000; includeSubDomains; preload;

Impact

Protocol Violation: HTTP specifications state that “authority” (HTTP/2 :authority pseudo-header) is strictly a request header and must not appear in responses

Client Compatibility: Some HTTP clients may reject or mishandle responses containing invalid headers

Security Concern: Leaking internal routing information (authority/host) in responses

Workaround

We can work around this issue by explicitly removing the header in the AssignMessage policy:

<Copy source="customResponse">

    <StatusCode>true</StatusCode>

    <ReasonPhrase>true</ReasonPhrase>

    <Payload>true</Payload>

    <Headers>

        <Header name="Content-Type"/>

    </Headers>

</Copy>

<Remove>

    <Headers>

        <Header name="authority"/>

        <Header name=":authority"/>

        <Header name="Host"/>

    </Headers>

</Remove>

<AssignTo createNew="false" transport="http" type="response"/>

Root Cause Analysis

Based on our investigation, we believe this occurs because:

Apigee’s ServiceCallout internally stores request metadata (including the Host/authority header used to call the target)

When copying the response using , Apigee incorrectly includes this request metadata in the response object

Even though we specify only certain headers to copy, the metadata leaks through

Please investigate and fix this issue in future releases. The workaround is functional but should not be necessary for proper HTTP protocol compliance.

Thanks for the detailed observations, including sharing details of the response you get from your backend and also the details for the workaround. If you have access to Apigee support, it would be great if you could raise this with support so they can raise this with the appropriate internal teams if it’s indeed a product issue.