{"record":{"id":"c2180536b44d50f0","repo":"AUTOMATIC1111/stable-diffusion-webui","slug":"multiple-data-pkl-found-in-filename","errorCode":null,"errorMessage":"Multiple data.pkl found in {filename}","messagePattern":"Multiple data\\.pkl found in (.+?)","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"modules/safe.py","lineNumber":91,"sourceCode":"        if allowed_zip_names_re.match(name):\r\n            continue\r\n\r\n        raise Exception(f\"bad file inside {filename}: {name}\")\r\n\r\n\r\ndef check_pt(filename, extra_handler):\r\n    try:\r\n\r\n        # new pytorch format is a zip file\r\n        with zipfile.ZipFile(filename) as z:\r\n            check_zip_filenames(filename, z.namelist())\r\n\r\n            # find filename of data.pkl in zip file: '<directory name>/data.pkl'\r\n            data_pkl_filenames = [f for f in z.namelist() if data_pkl_re.match(f)]\r\n            if len(data_pkl_filenames) == 0:\r\n                raise Exception(f\"data.pkl not found in {filename}\")\r\n            if len(data_pkl_filenames) > 1:\r\n                raise Exception(f\"Multiple data.pkl found in {filename}\")\r\n            with z.open(data_pkl_filenames[0]) as file:\r\n                unpickler = RestrictedUnpickler(file)\r\n                unpickler.extra_handler = extra_handler\r\n                unpickler.load()\r\n\r\n    except zipfile.BadZipfile:\r\n\r\n        # if it's not a zip file, it's an old pytorch format, with five objects written to pickle\r\n        with open(filename, \"rb\") as file:\r\n            unpickler = RestrictedUnpickler(file)\r\n            unpickler.extra_handler = extra_handler\r\n            for _ in range(5):\r\n                unpickler.load()\r\n\r\n\r\ndef load(filename, *args, **kwargs):\r\n    return load_with_extra(filename, *args, extra_handler=global_extra_handler, **kwargs)\r\n\r","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/AUTOMATIC1111/stable-diffusion-webui/blob/82a973c04367123ae98bd9abdf80d9eda9b910e2/modules/safe.py#L73-L109","documentation":"Raised by safe.py's check_pt() when scanning a PyTorch zip-format checkpoint (.ckpt/.pt). The new PyTorch serialization format stores the pickle payload in a file named '<dir>/data.pkl'; the security checker expects exactly one match for data_pkl_re in the archive's namelist. More than one match means the archive is malformed or was hand-assembled from multiple checkpoints, so the loader refuses to unpickle it.","triggerScenarios":"Calling load/embedding-checkpoint paths that run check_pt() on a file whose ZipFile.namelist() contains two or more entries matching the data.pkl regex (e.g. both 'archive/data.pkl' and 'foo/data.pkl'), typically after merging zipped checkpoints or re-zipping a model incorrectly.","commonSituations":"Merging two v1/v2 checkpoints with a script that concatenates zip entries instead of loading state dicts; manually repacking a .ckpt with 'zip -r'; downloading a corrupted or re-packaged model from a mirror.","solutions":["Re-export the model: load the state dict in PyTorch (torch.load) and re-save it with torch.save(state_dict, out.pt) so the archive has a single data.pkl","Prefer a safetensors copy of the same model if available; safetensors avoids the pickle path entirely","Inspect the archive with `python -m zipfile -l file.ckpt` to confirm the duplicate data.pkl entries","Re-download the checkpoint from the original source if the file may be corrupted"],"exampleFix":"# before: merging two zip checkpoints by concatenating entries (produces two data.pkl)\n# after: merge via state dicts and re-save\nimport torch\na = torch.load('a.ckpt', map_location='cpu')\nb = torch.load('b.ckpt', map_location='cpu')\na['state_dict'].update({k: 0.5*(v+b['state_dict'][k]) for k, v in a['state_dict'].items()})\ntorch.save(a, 'merged.ckpt')  # single data.pkl","handlingStrategy":"validation","validationCode":"import re, zipfile\ndata_pkl_re = re.compile(r'^[^/]+/data\\.pkl$')\ndef check_archive_has_single_pkl(path):\n    with zipfile.ZipFile(path) as z:\n        matches = [f for f in z.namelist() if data_pkl_re.match(f)]\n        if len(matches) != 1:\n            raise ValueError(f'{path}: expected 1 data.pkl, found {matches}')\n    return True","typeGuard":null,"tryCatchPattern":"try:\n    modules.safe.check_pt(path, extra_handler)\nexcept Exception as e:\n    if 'Multiple data.pkl' in str(e):\n        # re-export the checkpoint via state dicts, then retry\n        ...","preventionTips":["Only merge checkpoints by loading state dicts and re-saving with torch.save","Verify downloads with the publisher's checksum before loading","Prefer safetensors distribution formats when available"],"tags":["pytorch","checkpoint","zip","model-loading","pickle-security"],"backgroundTag":null,"analyzedSha":"82a973c04367123ae98bd9abdf80d9eda9b910e2","analyzedAt":"2026-08-14T16:46:43.225Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}