alibaba/nacos · error · FileNotFoundException

{getDescription()} cannot be resolved to URL

Error message

{getDescription()} cannot be resolved to URL

What it means

Default AbstractResource.getUrl() throws FileNotFoundException when a concrete resource subclass has not overridden getUrl() to produce a real URL. It is the base-class fallback: if no subclass supplies a URL, the resource 'cannot be resolved to a URL'. Encountered when an AbstractResource subclass is used in a context that calls getUrl() without implementing it.

Source

Thrown at common/src/main/java/com/alibaba/nacos/common/packagescan/resource/AbstractResource.java:111

    public boolean isOpen() {
        return false;
    }

    /**
     * This implementation always returns {@code false}.
     */
    @Override
    public boolean isFile() {
        return false;
    }

    /**
     * This implementation throws a FileNotFoundException, assuming
     * that the resource cannot be resolved to a URL.
     */
    @Override
    public URL getUrl() throws IOException {
        throw new FileNotFoundException(getDescription() + " cannot be resolved to URL");
    }

    /**
     * This implementation builds a URI based on the URL returned
     * by {@link #getUrl()}.
     */
    @Override
    public URI getUri() throws IOException {
        URL url = getUrl();
        try {
            return ResourceUtils.toUri(url);
        } catch (URISyntaxException ex) {
            throw new NestedIoException("Invalid URI [" + url + "]", ex);
        }
    }

    /**
     * This implementation throws a FileNotFoundException, assuming

View on GitHub (pinned to 9b989acdf1)

Solutions

  1. Override getUrl() in your AbstractResource subclass to return a real URL, or subclass a resource type that already provides one (ClassPathResource, FileSystemResource).
  2. If you only have a stream, use getInputStream() paths instead of getUrl().
  3. Prefer the concrete resource classes (ClassPathResource/UrlResource) that implement getUrl() correctly.
  4. In tests, return a real URL or avoid calling getUrl() on the stub.

Example fix

// before
class BytesResource extends AbstractResource {
    public InputStream getInputStream() { return new ByteArrayInputStream(bytes); }
}
URL u = res.getUrl(); // FileNotFoundException

// after — implement getUrl or use a concrete resource
class BytesResource extends AbstractResource {
    public InputStream getInputStream() { return new ByteArrayInputStream(bytes); }
    public URL getUrl() { return null /* or throw a typed error */; }
}
// better: use new ByteArrayResource(bytes) which supplies getInputStream only
Defensive patterns

Strategy: validation

Validate before calling

URL url;
try {
    url = resource.getUrl();
} catch (FileNotFoundException e) {
    url = null; // not URL-resolvable; use getInputStream instead
}

Type guard

boolean isUrlResolvable(Resource r) {
    try { r.getUrl(); return true; }
    catch (IOException e) { return false; }
}

Try / catch

try {
    URL u = resource.getUrl();
} catch (FileNotFoundException e) {
    log.debug("No URL for resource, using stream path");
}

Prevention

When it happens

Trigger: Calling getUrl() on a bare AbstractResource subclass (e.g. a custom resource that only implements getInputStream); a resource abstraction passed to code that resolves a URL for classpath or file access.

Common situations: Custom Resource implementation that wraps an in-memory stream but not a URL; passing an opaque resource to Nacos package-scan or HTTP helpers expecting a URL; a mock/test resource missing the override.

Related errors


AI-assisted analysis of alibaba/nacos@9b989acdf1 (2026-08-14). Data as JSON: /api/errors/5ff53913994e8333. Report an issue: GitHub.