roboflow/supervision · error · ValueError

Failed to parse XML root from {annotation_path}

Error message

Failed to parse XML root from {annotation_path}

What it means

Raised while loading a Pascal VOC dataset when ElementTree parses the annotation XML file but tree.getroot() returns None. This only happens for a structurally empty or degenerate XML document (e.g. a zero-byte or whitespace-only .xml file), because xml.etree.ElementTree.parse raises ParseError itself for malformed syntax. The file path is included so you can locate the offending annotation.

Source

Thrown at src/supervision/dataset/formats/pascal_voc.py:240

    classes: list[str] = []
    annotations = {}

    for image_path in tqdm(
        image_paths,
        total=len(image_paths),
        desc="Loading Pascal VOC annotations",
        disable=not show_progress,
    ):
        image_stem = Path(image_path).stem
        annotation_path = os.path.join(annotations_directory_path, f"{image_stem}.xml")
        if not os.path.exists(annotation_path):
            annotations[image_path] = Detections.empty()
            continue

        tree = parse(annotation_path)
        root = tree.getroot()
        if root is None:
            raise ValueError(f"Failed to parse XML root from {annotation_path}")

        image = cv2.imread(image_path)
        if image is None:
            raise ValueError(f"Could not read image from path: {image_path}")
        resolution_wh = (image.shape[1], image.shape[0])
        annotation, classes = detections_from_xml_obj(
            root, classes, resolution_wh, force_masks
        )
        annotations[image_path] = annotation

    return classes, image_paths, annotations


def detections_from_xml_obj(
    root: Element,
    classes: list[str],
    resolution_wh: tuple[int, int],
    force_masks: bool = False,

View on GitHub (pinned to 7f254d9784)

Solutions

  1. Check the file named in the error message with `cat`/`ls -la` — it is almost certainly empty or whitespace-only.
  2. Delete or regenerate the broken .xml file (re-export from the source dataset or re-download).
  3. Sweep the annotations directory for other empty XML files: find annotations_dir -name '*.xml' -size -1c
  4. If empty XML means 'no objects', decide whether to remove the file (the loader then treats the image as empty via the missing-file branch) or write a valid <annotation></annotation> root.

Example fix

# before: empty file annotations/0001.xml (0 bytes)
# after: minimal valid Pascal VOC file
with open('annotations/0001.xml', 'w') as f:
    f.write('<annotation></annotation>')
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path
import xml.etree.ElementTree as ET

def valid_voc_xml(path: str) -> bool:
    """Check that a Pascal VOC annotation file has a parseable root element."""
    p = Path(path)
    if not p.exists() or p.stat().st_size == 0:
        return False
    try:
        return ET.parse(p).getroot() is not None
    except ET.ParseError:
        return False

Try / catch

try:
    dataset = sv.DetectionDataset.from_pascal_voc(images_dir, ann_dir)
except ValueError as e:
    if 'Failed to parse XML root' in str(e):
        bad = str(e).split('from ')[-1].strip()
        Path(bad).unlink(missing_ok=True)  # or quarantine
        dataset = sv.DetectionDataset.from_pascal_voc(images_dir, ann_dir)
    else:
        raise

Prevention

When it happens

Trigger: Calling DetectionDataset.from_pascal_voc(...) (or the internal load loop in pascal_voc.py) where an image stem has a matching .xml file in the annotations directory that is empty, contains only whitespace, or is otherwise a valid-but-rootless document.

Common situations: Interrupted dataset downloads or exports that left 0-byte .xml files; annotation writers that flush an empty file before crashing; placeholder files created by tooling; filesystem corruption after a bad copy.

Understand the failure class

Related errors


AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15). Data as JSON: /api/errors/d7052e18d61c92e3. Report an issue: GitHub.