{"id":"056d5d92ef7ed245","repo":"gohugoio/hugo","slug":"failed-to-resolve-media-type-for-remote-resource","errorCode":null,"errorMessage":"failed to resolve media type for remote resource %q","messagePattern":"failed to resolve media type for remote resource %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"resources/resource_factories/create/remote.go","lineNumber":349,"sourceCode":"\t\t\t\tif exts != nil {\n\t\t\t\t\textensionHints = exts\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Look for a file extension. If it's .txt, look for a more specific.\n\t\t\tif extensionHints == nil || extensionHints[0] == \".txt\" {\n\t\t\t\tif ext := path.Ext(filename); ext != \"\" {\n\t\t\t\t\textensionHints = []string{ext}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Now resolve the media type primarily using the content.\n\t\t\tmediaType = media.FromContent(c.rs.MediaTypes(), extensionHints, body)\n\n\t\t}\n\n\t\tif mediaType.IsZero() {\n\t\t\treturn nil, fmt.Errorf(\"failed to resolve media type for remote resource %q\", uri)\n\t\t}\n\n\t\tuserKey = filename[:len(filename)-len(path.Ext(filename))] + \"_\" + userKey + mediaType.FirstSuffix.FullSuffix\n\t\tdata := responseToData(res, false, options.ResponseHeaders)\n\n\t\treturn c.rs.NewResource(\n\t\t\tresources.ResourceSourceDescriptor{\n\t\t\t\tMediaType:     mediaType,\n\t\t\t\tData:          data,\n\t\t\t\tGroupIdentity: identity.StringIdentity(optionsKey),\n\t\t\t\tLazyPublish:   true,\n\t\t\t\tOpenReadSeekCloser: func() (hugio.ReadSeekCloser, error) {\n\t\t\t\t\treturn hugio.NewReadSeekerNoOpCloser(bytes.NewReader(body)), nil\n\t\t\t\t},\n\t\t\t\tTargetPath: userKey,\n\t\t\t})\n\t})\n}","sourceCodeStart":331,"sourceCodeEnd":367,"githubUrl":"https://github.com/gohugoio/hugo/blob/8a468df065a75c1c7cf9f6850f32148746590ea5/resources/resource_factories/create/remote.go#L331-L367","documentation":"After fetching, Hugo must assign a media type to the remote resource so it can be processed and given a file suffix. It tries, in order: the Content-Type header (if configured/accepted), extensions derived from the content type, the URL path's file extension, and finally content sniffing via `media.FromContent`. If all of these yield nothing — typically a missing/garbage Content-Type, an extension-less URL, and unrecognizable bytes — Hugo cannot proceed and fails with this error. For HEAD requests there is no body to sniff, making this stricter.","triggerScenarios":"`resources.GetRemote` against endpoints returning no or bogus `Content-Type` (e.g. `application/octet-stream` for an unknown format) on URLs without a file extension (API routes like `/download?id=123`), HEAD-method requests where the header is the only signal and it maps to no known media type, or content types not present in Hugo's `mediaTypes` configuration and unsniffable content.","commonSituations":"Download endpoints and signed URLs (S3 presigned links) that omit extensions and serve `octet-stream`, custom or vendor MIME types (`application/vnd.*`) not in Hugo's media type table, and servers misconfigured to send empty Content-Type headers.","solutions":["Make the server send a correct `Content-Type` header, or use a URL variant that ends in a real file extension so Hugo can infer from the path.","Add the server's content type to your site config under `mediaTypes` (with a suffix) so `GetByType` resolves it.","If security config filters accepted types, review `security.http.mediaTypes` to ensure the returned Content-Type is allowed.","Avoid HEAD for such endpoints — use GET so content sniffing can run on the body."],"exampleFix":"# config: teach Hugo the server's content type\n# before: (no mediaTypes entry, server sends application/vnd.foo)\n# after (hugo.toml)\n[mediaTypes.'application/vnd.foo']\nsuffixes = ['foo']","handlingStrategy":"validation","validationCode":"{{/* give Hugo something to resolve the type from: extension or explicit mediaType */}}\n{{ $r := resources.GetRemote \"https://api.example.com/render?id=42\" (dict \"headers\" (dict \"Accept\" \"image/png\")) }}\n{{/* or force it: */}}\n{{ $r := resources.GetRemote $url | resources.Copy \"images/chart.png\" }}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer URLs whose path ends in a real file extension; extensionless API endpoints commonly trigger this","If the server returns a generic or missing Content-Type, use resources.Copy to a name with the correct extension so the type is derivable","For truly custom formats, register the media type/suffix in site config (mediaTypes) before fetching","Check the endpoint's Content-Type header with curl -I when diagnosing — the server may send application/octet-stream"],"tags":["hugo","get-remote","media-type","content-type","mime"],"analyzedSha":"8a468df065a75c1c7cf9f6850f32148746590ea5","analyzedAt":"2026-07-31T21:23:07.045Z","schemaVersion":2}