apache/beam · error · RuntimeException

Cannot resolve artifact information

Error message

Cannot resolve artifact information: %s

What it means

DefaultArtifactResolver's resolve function iterates all registered resolution functions; if none can resolve the artifact staging information, it throws a RuntimeException. It means no registered resolver (local file, staged file, etc.) knows how to turn the artifact into retrievable ArtifactInformation.

Solutions

  1. Register a custom ResolutionFn via DefaultArtifactResolver.register that handles the unresolvable artifact type
  2. Use the standard environment/artifact staging flow so artifacts get a supported type URN
  3. Check SDK/runner version mismatch and align versions so built-in resolvers cover the artifact types

Example fix

// before
new DefaultArtifactResolver().resolve(artifactInformation);
// after
DefaultArtifactResolver resolver = new DefaultArtifactResolver();
resolver.register(info -> myCustomResolve(info)); // handle the unknown type first
List<RunnerApi.ArtifactInformation> resolved = resolver.resolve(artifactInformation);
Defensive patterns

Strategy: validation

Validate before calling

// before resolving, check the artifact type URN is one your resolvers support
if (!SUPPORTED_ARTIFACTURNS.contains(info.getTypeUrn())) {
  throw new IllegalStateException("Unhandled artifact type: " + info.getTypeUrn());
}

Try / catch

try { resolved = resolver.resolve(info); } catch (RuntimeException e) { if (e.getMessage().startsWith("Cannot resolve artifact information")) { /* register a fallback ResolutionFn */ } }

Prevention

When it happens

Trigger: Calling the resolver with an ArtifactInformation whose type URN or role payload matches no registered ResolutionFn — e.g. artifacts staged with an unsupported environment type or a custom artifact type during pipeline translation/retrieval.

Common situations: Running a portable pipeline with artifacts staged by a different runner/SDK version; custom environments whose artifacts bypass standard resolvers; cross-language pipelines where the staging service produced an unfamiliar artifact type.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of apache/beam@12126d8942 (2026-09-13). Data as JSON: /api/errors/aa22fc827db656cf. Report an issue: GitHub.

Appendix: source

Thrown at sdks/java/core/src/main/java/org/apache/beam/sdk/util/construction/DefaultArtifactResolver.java:66

              return Optional.of(ImmutableList.of(info));
            } else {
              return Optional.empty();
            }
          });

  private synchronized List<ResolutionFn> regesteredFns() {
    return ImmutableList.copyOf(fns);
  }

  private Function<RunnerApi.ArtifactInformation, Stream<RunnerApi.ArtifactInformation>> resolver =
      (info) -> {
        for (ResolutionFn fn : Lists.reverse(regesteredFns())) {
          Optional<List<RunnerApi.ArtifactInformation>> resolved = fn.resolve(info);
          if (resolved.isPresent()) {
            return resolved.get().stream();
          }
        }
        throw new RuntimeException(String.format("Cannot resolve artifact information: %s", info));
      };

  @Override
  public synchronized void register(ResolutionFn fn) {
    fns.add(fn);
  }

  @Override
  public List<RunnerApi.ArtifactInformation> resolveArtifacts(
      List<RunnerApi.ArtifactInformation> artifacts) {
    for (ResolutionFn fn : Lists.reverse(regesteredFns())) {
      List<RunnerApi.ArtifactInformation> moreResolved = new ArrayList<>();
      for (RunnerApi.ArtifactInformation artifact : artifacts) {
        Optional<List<RunnerApi.ArtifactInformation>> resolved = fn.resolve(artifact);
        if (resolved.isPresent()) {
          moreResolved.addAll(resolved.get());
        } else {
          moreResolved.add(artifact);

View on GitHub (pinned to 12126d8942)