Every code SvgSecurityCheck reports, its message, and what to change so the file is accepted. The
message is the template with the detail filled in at %s. Codes never change once
released; message wording can, so match on code.
| Code | Message | What to do |
|---|---|---|
file-unreadable |
Cannot read file %s |
Pass the upload's tmp_name, check $_FILES['logo']['error'] first, and run the check before move_uploaded_file(). |
not-svg |
This is not an SVG file: it starts with %s |
Export the file as SVG from the design tool. Renaming a PNG or PDF does not convert it. |
not-utf8 |
SVG files must be UTF-8, this one is %s |
Save the file as UTF-8. When the detail says "declared as", also change encoding="..." in the first line to encoding="UTF-8". Every design tool and code editor does this by default; older Windows Notepad wrote UTF-16 when "Unicode" was picked in Save As. |
malformed-xml |
The SVG is not well-formed XML: %s |
The detail names the line. An HTML entity such as is the usual cause in a hand-edited file: write   or the character itself. "Input is not proper UTF-8" means the file was saved in another encoding: save it as UTF-8. An unclosed tag means a hand edit or a truncated transfer, and "no root element" means no <svg> tag near the start: re-export. |
doctype-not-allowed |
The DOCTYPE declaration is not allowed because %s |
In Illustrator, uncheck "Preserve Illustrator Editing Capabilities" in SVG Options and export again. Keep the .ai file as the editable copy. When the detail mentions >, delete the <!DOCTYPE ...> line; an SVG file does not need one. |
processing-instruction |
Processing instructions like <?%s?> are not allowed |
Remove the instruction. For <?xml-stylesheet?>, first copy the CSS from the file it names into a <style> element. An xpacket marker that holds > is not from a design tool: re-export the file. |
comment-not-allowed |
A comment starting with <!--%s is not allowed, HTML parsers close it there |
Put a space or any text after <!--. |
cdata-not-allowed |
A CDATA section containing > is not allowed inside <%s>, HTML parsers end it there |
Write the title or description as plain text, with > as >. |
element-in-title-or-desc |
<title> and <desc> may hold only text, not <%s> |
Write the title or description as plain text. No design tool puts elements there; one in the file was added by hand. |
root-not-svg |
The root element must be <svg>, not <%s> |
Upload the SVG file itself, not an HTML page that contains it. |
root-namespace-wrong |
The root <svg> element must declare xmlns="http://www.w3.org/2000/svg", but it has %s |
Set xmlns="http://www.w3.org/2000/svg" on the root element. Snippets copied out of a web page are missing it; design tools always write it. |
element-not-allowed |
<%s> is not allowed in uploaded SVGs |
Remove the element. Older Inkscape wrote <flowRoot> for a dragged text box: select the text, then Text → Convert to Text, or Path → Object to Path. draw.io writes <foreignObject> for formatted labels: set the labels to plain text before exporting. Inkscape arrowheads are <marker>: select the line, then Path → Stroke to Path. |
namespace-not-allowed |
Elements from the XML namespace %s are not allowed |
Remove the element. Inkscape, Illustrator, Affinity Designer, Sketch and Visio metadata is ignored and never triggers this; XHTML, MathML and anything unknown do. If a current design tool wrote it, open an issue with the file. |
element-prefix-wrong |
<%s> has the wrong prefix: SVG elements take none, metadata elements need one |
Write SVG elements without a prefix, as design tools do: <rect>, not <svg:rect>, with xmlns="http://www.w3.org/2000/svg" on the root. A metadata element with no prefix comes from a hand edit: give it a prefix bound to its namespace, or remove it. |
event-handler |
%s= event handler attributes are not allowed |
Remove the attribute. No design tool writes one. |
attribute-not-allowed |
The %s attribute is not allowed |
Remove the attribute. If a current design tool wrote it, open an issue with the file. |
xlink-prefix-wrong |
The xlink: prefix must be bound to http://www.w3.org/1999/xlink, not %s |
Declare xmlns:xlink="http://www.w3.org/1999/xlink", as every design tool does. A file that binds xlink to another namespace was edited by hand: re-export it. |
href-not-allowed |
href must reference an element in the same file (#id), not %s |
Copy the referenced element into this file and point at it with #id. For a link (<a>), remove it from the artwork and wrap the <img> tag in the page with the link instead. |
image-href-not-allowed |
Image href must be #id or an embedded PNG, JPEG, GIF, WebP or SVG data: URL, not %s |
Export with images embedded. Illustrator: Image Location → Embed. Inkscape: "Embed images" in Save As, or select the image and use Extensions → Images → Embed Images. Affinity Designer: "Embed images" under More on the export panel. Figma always embeds. If the image is already embedded but in another format, such as AVIF, or without ;base64,, convert it to PNG or JPEG and embed it again. |
embedded-svg-not-allowed |
An embedded SVG image was rejected: %s |
Fix the inner SVG, or embed a PNG instead. When the detail is the inner file's message, its row on this page has the fix. |
url-not-fragment |
url() in the %s attribute must reference an element in the same file (#id) |
Define the gradient, pattern, filter or mask in this file and reference it with url(#id). |
reference-expansion-too-large |
The references in this file %s |
For a loop, the detail names it: break it. For a count, flatten the repeated art in the design tool. The limit is SvgSecurityCheck::$maxExpandedElements. |
css-not-allowed |
CSS containing %s is not allowed |
For a url( to a font or an @import, embed the font as src: url(data:font/woff2;base64,...) in @font-face (the type must start with font/), or convert text to outlines (Illustrator: Type → Create Outlines; Figma: Outline Text; Inkscape: Path → Object to Path). For any other url(, define the element in this file and reference it with url(#id). For a backslash, write the value without escapes. For the size limit, convert text to outlines instead of embedding fonts. For any other function or at-rule, remove it, or open an issue with the file. |
animation-target-not-allowed |
Animating the %s attribute is not allowed |
Animate a presentation attribute such as fill, opacity or transform instead, or switch between two elements with visibility. |
To translate a message, run template through your translation function, put detail back
with sprintf(), and encode the whole result, since the template itself holds angle brackets:
echo htmlspecialchars(sprintf(t($violation->template), $violation->detail));Every template is in Violation::TEMPLATES, keyed by code, so a translation system can
register them all up front.
Three things to know when reading a result:
- A small malformed file reports only
malformed-xml. libxml2 parses in chunks and discards the chunk holding the error, and in a small file that chunk is the whole file. Fix the XML and check again; the other problems are reported then. - The file name in a
file-unreadablemessage shows which step went wrong. A temporary name such asphp3F.tmpmeansmove_uploaded_file()ran before the check. The visitor's own file name, such aslogo.svg, meansnamewas passed instead oftmp_name. No name at all means the upload failed: check$_FILES['logo']['error']. - The same problem on five elements is reported once. Errors are deduplicated by code
and detail: five
<script>elements are one error, five differenton*attributes are five. The list stops atSvgSecurityCheck::$maxErrorsdistinct problems (50 by default).