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
- Check the file named in the error message with `cat`/`ls -la` — it is almost certainly empty or whitespace-only.
- Delete or regenerate the broken .xml file (re-export from the source dataset or re-download).
- Sweep the annotations directory for other empty XML files: find annotations_dir -name '*.xml' -size -1c
- 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
- Validate dataset archives after download (check for 0-byte XML files).
- Keep annotation writers atomic: write to a temp file and rename on success.
- Run a one-off sweep: find annotations -name '*.xml' -size -1c before loading.
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
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Missing bndbox in Pascal VOC annotation.
- Missing polygon coordinate value in Pascal VOC.
- Missing '{tag}' in Pascal VOC annotation.
- Could not read image from path: {image_path}
- Detections must have class_id attribute.
AI-assisted analysis of roboflow/supervision@7f254d9784 (2026-08-15).
Data as JSON: /api/errors/d7052e18d61c92e3.
Report an issue: GitHub.