withastro/astro · error · AstroError
FailedToFetchRemoteImageDimensions
FailedToFetchRemoteImageDimensions
Error message
Failed to get the dimensions for ${url}. What it means
First guard in inferRemoteSize(): URL.canParse(url) returned false, so Astro rejects the input before any network call. Code FailedToFetchRemoteImageDimensions, message embeds the offending url. This is purely an input-validation failure, not a network problem.
Source
Thrown at packages/astro/src/assets/utils/remoteProbe.ts:23
import { imageMetadata } from './metadata.js';
import { fetchWithRedirects } from './redirectValidation.js';
type RemoteImageConfig = Pick<AstroConfig['image'], 'domains' | 'remotePatterns'>;
/**
* Infers the dimensions of a remote image by streaming its data and analyzing it progressively until sufficient metadata is available.
*
* @param {string} url - The URL of the remote image from which to infer size metadata.
* @param {RemoteImageConfig} [imageConfig] - Optional image config used to validate remote allowlists.
* @return {Promise<Omit<ImageMetadata, 'src' | 'fsPath'>>} Returns a promise that resolves to an object containing the image dimensions metadata excluding `src` and `fsPath`.
* @throws {AstroError} Thrown when the fetching fails or metadata cannot be extracted.
*/
export async function inferRemoteSize(
url: string,
imageConfig?: RemoteImageConfig,
): Promise<Omit<ImageMetadata, 'src' | 'fsPath'>> {
if (!URL.canParse(url)) {
throw new AstroError({
...AstroErrorData.FailedToFetchRemoteImageDimensions,
message: AstroErrorData.FailedToFetchRemoteImageDimensions.message(url),
});
}
const allowlistConfig = imageConfig
? {
domains: imageConfig.domains ?? [],
remotePatterns: imageConfig.remotePatterns ?? [],
}
: undefined;
if (!allowlistConfig) {
const parsedUrl = new URL(url);
if (!['http:', 'https:'].includes(parsedUrl.protocol)) {
throw new AstroError({
...AstroErrorData.FailedToFetchRemoteImageDimensions,
message: AstroErrorData.FailedToFetchRemoteImageDimensions.message(url),View on GitHub (pinned to d081033d5f)
Solutions
- Confirm the src is a fully-qualified absolute URL with scheme, e.g. `https://cdn.example.com/img.png`.
- Guard the CMS-supplied value: skip the Image or fall back when the field is empty.
- If the asset is local, move it into src/assets and import it, or put it in public/ and drop inferSize.
- Log the value right before render to catch undefined/empty inputs.
Example fix
// before
<Image src={post.coverUrl} inferSize alt="…" /> // coverUrl is undefined
// after
{post.coverUrl && <Image src={post.coverUrl} inferSize alt="…" />} Defensive patterns
Strategy: validation
Validate before calling
function isAbsoluteUrl(v: unknown): v is string {
return typeof v === 'string' && URL.canParse(v) && /^https?:/.test(v);
}
// before render:
if (!isAbsoluteUrl(src)) { /* fall back / skip inferSize */ } Type guard
function isRemoteUrl(v: unknown): v is string {
return typeof v === 'string' && URL.canParse(v) && ['http:','https:'].includes(new URL(v).protocol);
} Prevention
- Never pass undefined/empty CMS fields to inferSize.
- Validate URLs at the data layer, not in the template.
- Use a typed schema (zod) for CMS image fields.
When it happens
Trigger: Passing inferSize on a remote Image whose src is not a valid absolute URL — undefined, an empty string, a relative path, or a malformed string that the URL constructor rejects. Reached when an <Image src="…" inferSize /> or getImage({ src, inferSize: true }) points at a remote string.
Common situations: Reading src from a CMS field that was empty/undefined; building the URL from an env var that was not set; passing a relative path like '/images/x.png' (which belongs in public/) instead of an absolute https URL; a typo stripping the scheme.
Related errors
- SVG file does not contain an <svg> element
- NoImageMetadata
- RemoteImageNotAllowed
- NoImageMetadata
- ImageNotFound
AI-assisted analysis of withastro/astro@d081033d5f (2026-08-12).
Data as JSON: /api/errors/9ef9ffa9d0a08d1c.
Report an issue: GitHub.