gatsbyjs/gatsby · error
Remote file node is null
Error message
Remote file node is null
What it means
Thrown in gatsby-transformer-screenshot's gatsby-node.js after calling createRemoteFileNode with a screenshot URL. createRemoteFileNode is expected to return a file node object; if it returns null or undefined, the screenshot was not successfully downloaded and turned into a Gatsby File node, so the build cannot proceed.
Source
Thrown at packages/gatsby-transformer-screenshot/src/gatsby-node.js:159
expires = new Date(2999, 1, 1).getTime()
} else {
const screenshotResponse = await axios.post(
pluginOptions.screenshotEndpoint,
{ url }
)
fileNode = await createRemoteFileNode({
url: screenshotResponse.data.url,
cache,
createNode,
createNodeId,
getCache,
parentNodeId,
})
expires = screenshotResponse.data.expires
if (!fileNode) {
throw new Error(`Remote file node is null`, screenshotResponse.data.url)
}
}
const screenshotNode = {
id: createNodeId(`${parent} >>> Screenshot`),
url,
expires,
parent,
children: [],
internal: {
type: `Screenshot`,
},
screenshotFile___NODE: fileNode.id,
usingPlaceholder: USE_PLACEHOLDER_IMAGE,
}
screenshotNode.internal.contentDigest = createContentDigest(screenshotNode)
View on GitHub (pinned to 8b06340921)
Solutions
- Verify the screenshot URL from screenshotResponse.data.url is reachable from the build machine: `curl -I <url>`.
- Check that the screenshot Lambda completed and uploaded the image to S3 before the build node queries it (race condition between putFile and getFile).
- If behind a proxy, configure HTTP_PROXY/HTTPS_PROXY so createRemoteFileNode can reach the URL.
- Retry the build after confirming network connectivity; add logging around the createRemoteFileNode call to inspect the response.
Example fix
// before
fileNode = await createRemoteFileNode({
url: screenshotResponse.data.url,
// ...
})
if (!fileNode) {
throw new Error(`Remote file node is null`, screenshotResponse.data.url)
}
// after — log and retry before failing
fileNode = await createRemoteFileNode({ url, cache, createNode, createNodeId, getCache, parentNodeId })
if (!fileNode) {
console.warn(`Screenshot not ready at ${url}, retrying once...`)
await new Promise(r => setTimeout(r, 5000))
fileNode = await createRemoteFileNode({ url, cache, createNode, createNodeId, getCache, parentNodeId })
}
if (!fileNode) throw new Error(`Remote file node is null for ${url}`) Defensive patterns
Strategy: retry
Validate before calling
// Validate URL reachability before passing to createRemoteFileNode
const http = require('http')
const https = require('https')
function checkUrl(url) {
return new Promise(resolve => {
const mod = url.startsWith('https') ? https : http
mod.request(url, { method: 'HEAD' }, res => resolve(res.statusCode === 200))
.on('error', () => resolve(false))
.end()
})
} Try / catch
// Retry with backoff before giving up
async function createFileNodeWithRetry(url, deps, retries = 3) {
for (let i = 0; i < retries; i++) {
const fileNode = await createRemoteFileNode({ url, ...deps })
if (fileNode) return fileNode
await new Promise(r => setTimeout(r, 2000 * (i + 1)))
}
throw new Error(`Remote file node is null after ${retries} retries for ${url}`)
} Prevention
- Add retry logic with exponential backoff around createRemoteFileNode for flaky remote sources.
- Log the screenshot URL and response status to diagnose intermittent failures.
- Ensure the screenshot Lambda and build share a consistent S3 region.
- Configure HTTP_PROXY if the build environment requires a proxy for outbound calls.
When it happens
Trigger: createRemoteFileNode is called with the URL from the screenshot service response, but returns falsy. This can happen when the remote download fails silently, the URL is unreachable from the build environment, or there is a network/timeout issue during 'gatsby build'.
Common situations: Build environment has no outbound internet access (e.g. corporate proxy, restricted CI), the screenshot service Lambda returned a URL that has expired or is not yet available, DNS resolution fails, or the remote server returns a non-200 status that createRemoteFileNode swallows.
Related errors
- {"fetchError":"Could not fetch ${pathOrUrl} from official re
- Something went wrong when trying to add the plugins to the p
- Cannot access Contentful space "${maskText(pluginOptions.spa
- url passed to createRemoteFileNode is either missing or not
- Source GraphQL API: HTTP error ${response.status} ${response
AI-assisted analysis of gatsbyjs/gatsby@8b06340921 (2026-08-13).
Data as JSON: /api/errors/ce87984790352e5b.
Report an issue: GitHub.