{"record":{"id":"27bfe6d890b172ed","repo":"GoogleContainerTools/jib","slug":"blob-not-available-for-reference-layer","errorCode":null,"errorMessage":"Blob not available for reference layer","messagePattern":"Blob not available for reference layer","errorType":"exception","errorClass":"LayerPropertyNotFoundException","httpStatus":null,"severity":"error","filePath":"jib-core/src/main/java/com/google/cloud/tools/jib/image/ReferenceLayer.java","lineNumber":48,"sourceCode":"  private final BlobDescriptor blobDescriptor;\n\n  /** The digest of the uncompressed layer content. */\n  private final DescriptorDigest diffId;\n\n  /**\n   * Instantiate with a {@link BlobDescriptor} and diff ID.\n   *\n   * @param blobDescriptor the blob descriptor\n   * @param diffId the diff ID\n   */\n  public ReferenceLayer(BlobDescriptor blobDescriptor, DescriptorDigest diffId) {\n    this.blobDescriptor = blobDescriptor;\n    this.diffId = diffId;\n  }\n\n  @Override\n  public Blob getBlob() throws LayerPropertyNotFoundException {\n    throw new LayerPropertyNotFoundException(\"Blob not available for reference layer\");\n  }\n\n  @Override\n  public BlobDescriptor getBlobDescriptor() {\n    return blobDescriptor;\n  }\n\n  @Override\n  public DescriptorDigest getDiffId() {\n    return diffId;\n  }\n}\n","sourceCodeStart":30,"sourceCodeEnd":61,"githubUrl":"https://github.com/GoogleContainerTools/jib/blob/fb949e2676afbbd7dd7a1ef61e20251931325654/jib-core/src/main/java/com/google/cloud/tools/jib/image/ReferenceLayer.java#L30-L61","documentation":"ReferenceLayer is a metadata-only view of a layer (blob descriptor + diff ID) referenced from a manifest; it does not hold the layer's compressed content. getBlob() therefore throws LayerPropertyNotFoundException.","triggerScenarios":"Calling Layer.getBlob() on a ReferenceLayer created via ReferenceLayer.of(blobDescriptor, diffId) or returned by JsonToImageTranslator.toImage.","commonSituations":"Pulling an image via the registry API and then trying to stream layer blobs from the in-memory Image object; migrating manifests where content was never downloaded; tests assuming getBlob() works on all layers.","solutions":["Fetch the blob content from the registry (RegistryClient layer pull) using the layer digest instead of getBlob()","Use a CachedLayer from the layer cache when local content is needed","Guard with instanceof checks and only call getBlob() on layers that carry content"],"exampleFix":"// before\nBlob blob = layer.getBlob();\n// after\nif (layer instanceof CachedLayer) {\n  Blob blob = ((CachedLayer) layer).getBlob();\n} else {\n  DescriptorDigest digest = layer.getBlobDescriptor().getDigest();\n}","handlingStrategy":"type-guard","validationCode":"boolean canGetBlob = layer instanceof CachedLayer;","typeGuard":"boolean hasBlobContent(Layer l) { return l instanceof CachedLayer; }","tryCatchPattern":"try { Blob b = layer.getBlob(); } catch (LayerPropertyNotFoundException e) { pullBlobFromRegistry(layer.getBlobDescriptor().getDigest()); }","preventionTips":["ReferenceLayer is metadata-only; never expect content from it","Download blobs with RegistryClient using the layer digest","Use the layer cache for local blob access"],"tags":["jib","docker-image","layer","reference-layer"],"backgroundTag":"unsupported-operation","analyzedSha":"fb949e2676afbbd7dd7a1ef61e20251931325654","analyzedAt":"2026-09-06T14:04:09.491Z","contentChangedAt":"2026-09-06T14:04:09.491Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}