MDS027: cross-file-reference-integrity
Links to local files and heading anchors must resolve.
# Settings
| Setting | Type | Default | Description |
|---|---|---|---|
include | list | [] | glob patterns to include |
exclude | list | [] | glob patterns to skip |
strict | bool | false | check non-Markdown file links |
placeholders | list | [] | Placeholder tokens to treat as opaque; see placeholder grammar |
wikilinks | bool | false | Validate Obsidian-style [[Page]], [[Page#anchor]], [[Page|alias]], and ![[file.png]] targets against the workspace. |
wikilink-style | string | "obsidian" | Resolution style for wikilinks. Only obsidian ships today; other values are rejected at config load. |
Useful tokens: var-token, heading-question, placeholder-section.
With strict: false, only Markdown targets (.md, .markdown)
are checked (except images — see links.validate-images).
External links (http:, https:, mailto:) are always ignored.
# links block
| Setting | Type | Default | Description |
|---|---|---|---|
links.validate-images | bool | true | Check *ast.Image targets (e.g. ) regardless of strict mode. |
links.validate-reference-style | bool | true | Check reference-style link targets (e.g. [text][label] / [label]: url). |
links.site-root | string | "" | When set, resolve absolute paths (e.g. /docs/rules/) against this directory on disk. |
When links.validate-images is on, image targets are checked even
when strict: false — an image  is flagged as a
broken target regardless of extension. Set to false to restore the
pre-hardening behavior where images were silently skipped.
When links.site-root is unset, absolute-path links (/foo/bar)
are silently skipped (the behavior before this setting was added).
# Wikilinks
wikilinks: true resolves every Obsidian-style wikilink
in the source against the workspace root.
Resolution is by file stem (case-insensitive) for
.md/.markdown targets. Other extensions match by
exact filename. The shortest matching path wins; ties
break alphabetically.
Unresolved targets, missing heading anchors, and unreadable targets each emit one diagnostic.
Wikilinks inside fenced code blocks, code spans, and
<?...?> directive markers are never flagged. The
placeholders filter applies to wikilink targets the
same way it applies to standard Markdown link
destinations.
The obsidian convention turns this on with
wikilink-style: obsidian in one switch — see the
conventions reference
.
# Config
rules:
cross-file-reference-integrity:
include:
- "docs/**"
exclude:
- "docs/generated/**"
strict: false
links:
site-root: ""
validate-images: true
validate-reference-style: trueDisable:
rules:
cross-file-reference-integrity: false# Examples
# Good
# Cross File Links
See [guide](good/guide.md#overview).
Jump to the [local section](#local-anchor).
## Local Anchor
Anchor target.# Good – guide target
# Guide
## Overview
This file is a valid link target.# Bad – missing file
# Broken File Link
See [guide](bad/missing.md).# Bad – missing anchor
# Broken Heading Link
See [guide](bad/ref/guide.md#missing-section).# Diagnostics
| Condition | Message |
|---|---|
| missing file | broken link target “x.md” not found |
| missing heading | broken link target “x.md#section” has no matching heading anchor |
# See also
# Meta-Information
- ID: MDS027
- Name:
cross-file-reference-integrity - Status: ready
- Default: enabled, include: [], exclude: [], strict: false, links.validate-images: true, links.validate-reference-style: true, links.site-root: ""
- Fixable: no
- Implementation: source
- Category: link
- markdownlint: MD051 (link-fragments) (partial)
- rumdl: MD051 (link-fragments) (partial)
- panache: undefined-anchor
- gomarklint: link-fragments (partial)