apache/kafka · error · Exception

Unexpected contents in the artifact. Exactly one version…

Error message

Unexpected contents in the artifact. Exactly one version directory is expected.

What it means

docker/extract_docker_official_image_artifact.py:extract_artifact unzips a release artifact into a temp dir and asserts that it contains exactly one top-level entry, which it treats as the version directory. If the zip has zero entries (empty) or more than one (e.g. multiple version dirs, a stray README at the root, or a nested layout), it raises Exception with this message.

Solutions

  1. Inspect the artifact: `unzip -l artifact.zip` and confirm there is exactly one top-level directory.
  2. Re-package so the version directory is the sole top-level entry (strip stray READMEs, __MACOSX, sibling dirs).
  3. If multiple versions are legitimately present, extract only the target version dir and pass a single-version zip to this script.
  4. Verify you are feeding the artifact produced by the official release process, not a staging bundle.

Example fix

# before
$ python3 docker/extract_docker_official_image_artifact.py mixed.zip
# zip contains: 3.7.0/, 3.6.2/, README.md -> Exception: Unexpected contents...

# after
$ unzip -l single.zip
   3.7.0/jvm/Dockerfile
   3.7.0/native/Dockerfile
$ python3 docker/extract_docker_official_image_artifact.py single.zip  # ok
Defensive patterns

Strategy: validation

Validate before calling

import zipfile
with zipfile.ZipFile(artifact_path) as z:
    roots = {n.split('/')[0] for n in z.namelist() if n}
if len(roots) != 1:
    raise SystemExit(f"artifact must contain exactly one top-level dir, found: {sorted(roots)}")

Type guard

null

Try / catch

try:
    extract_artifact(artifact_path)
except Exception as e:
    print(f"{e}; inspect with `unzip -l {artifact_path}`", file=sys.stderr)
    raise

Prevention

When it happens

Trigger: Passing a zip whose top level is anything other than a single directory - for example two sibling version folders, or files placed at the zip root alongside the version folder, or an empty zip.

Common situations: Uploading the wrong artifact (e.g. a tar.gz renamed to .zip, or a parent archive containing multiple version zips); CI producing an artifact with a top-level metadata file; manual repackaging that added a macOS __MACOSX folder.

Related errors


AI-assisted analysis of apache/kafka@996fb4585a (2026-08-11). Data as JSON: /api/errors/89c37a5287af958d. Report an issue: GitHub.

Appendix: source

Thrown at docker/extract_docker_official_image_artifact.py:58

def set_executable_permissions(directory):
    for root, _, files in os.walk(directory):
        for file in files:
            path = os.path.join(root, file)
            os.chmod(path, os.stat(path).st_mode | 0o111)


def extract_artifact(artifact_path):
    docker_official_images_dir = Path(os.path.dirname(os.path.realpath(__file__)), "docker_official_images")
    temp_dir = Path('temp_extracted')
    try:
        if temp_dir.exists():
            shutil.rmtree(temp_dir)  
        temp_dir.mkdir()
        with zipfile.ZipFile(artifact_path, 'r') as zip_ref:
            zip_ref.extractall(temp_dir)
        artifact_version_dirs = list(temp_dir.iterdir())
        if len(artifact_version_dirs) != 1:
            raise Exception("Unexpected contents in the artifact. Exactly one version directory is expected.")
        artifact_version_dir = artifact_version_dirs[0]
        target_version_dir =  Path(os.path.join(docker_official_images_dir, artifact_version_dir.name))
        target_version_dir.mkdir(parents=True, exist_ok=True)
        for image_type_dir in artifact_version_dir.iterdir():
            target_image_type_dir = Path(os.path.join(target_version_dir, image_type_dir.name))
            if target_image_type_dir.exists():
                shutil.rmtree(target_image_type_dir)            
            shutil.copytree(image_type_dir, target_image_type_dir)
            set_executable_permissions(target_image_type_dir)
    finally:
        if temp_dir.exists():
            shutil.rmtree(temp_dir)

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("--path_to_downloaded_artifact", "-artifact_path", required=True,
                        dest="artifact_path", help="Path to zipped artifacy downloaded from github actions workflow.")
    args = parser.parse_args()

View on GitHub (pinned to 996fb4585a)