gatsbyjs/gatsby · error · Error

Source GraphQL API: HTTP error ${response.status} ${response

Error message

Source GraphQL API: HTTP error ${response.status} ${response.statusText}

What it means

gatsby-source-graphql wraps every outbound GraphQL fetch in node-fetch and throws when the HTTP response status is 400 or above. The message surfaces status code and statusText from the remote server so the user can see whether it is an auth failure (401/403), a client error (400), or a server error (5xx). The error is thrown from the Apollo Link fetch polyfill, so it propagates through the Apollo client into the sourcing pipeline.

Source

Thrown at packages/gatsby-source-graphql/src/fetch.js:10

const nodeFetch = require(`node-fetch`).default

// this is passed to the Apollo Link
// https://www.apollographql.com/docs/link/links/http/#fetch-polyfill

exports.fetchWrapper = async (uri, options) => {
  const response = await nodeFetch(uri, options)

  if (response.status >= 400) {
    throw new Error(
      `Source GraphQL API: HTTP error ${response.status} ${response.statusText}`
    )
  }

  return response
}

View on GitHub (pinned to 8b06340921)

Solutions

  1. Verify the url in plugin options resolves to the GraphQL endpoint (curl -i with the same headers).
  2. Confirm authentication headers (Authorization, custom tokens) are present and valid in the current environment.
  3. Check the remote server health — a 5xx is upstream; retry later or contact the API provider.
  4. If a 400, run the failing query against the endpoint directly to see the GraphQL error details.

Example fix

// before
resolve: `gatsby-source-graphql`,
options: { url: `https://api.example.com/graphql` }

// after
resolve: `gatsby-source-graphql`,
options: {
  url: `https://api.example.com/graphql`,
  headers: { Authorization: `Bearer ${process.env.API_TOKEN}` },
}
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

try { await apolloClient.query({ query }) } catch (e) { if (/Source GraphQL API: HTTP error/.test(e.message)) { const code = e.message.match(/HTTP error (\d+)/)?.[1]; reporter.panic(`Remote GraphQL endpoint returned ${code}; check url and auth`) } throw e }

Prevention

When it happens

Trigger: Remote GraphQL endpoint returns 401/403 (bad or expired token); 404 from a wrong URL; 400 from a malformed query body; 5xx from upstream outage; CORS/network proxy returning a 502; rate-limited endpoint returning 429.

Common situations: Typo in the GraphQL endpoint url; expired API key or missing Authorization header; remote schema changed and queries now reference removed fields; environment variable holding the token not set in CI; reverse proxy in front of the GraphQL API returning HTML error pages.

Related errors


AI-assisted analysis of gatsbyjs/gatsby@8b06340921 (2026-08-13). Data as JSON: /api/errors/cebe6b7c06b1f9fd. Report an issue: GitHub.