{"record":{"id":"230a423d7462a41a","repo":"dotnet/wpf","slug":"invalidlicense-230a42","errorCode":"InvalidLicense","errorMessage":"RightsManagementFailureCode.InvalidLicense","messagePattern":"RightsManagementFailureCode\\.InvalidLicense","errorType":"error_code","errorClass":"RightsManagementException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Security/RightsManagement/PublishLicense.cs","lineNumber":36,"sourceCode":"        /// This constructor accepts a string representation of a Publish License, which is supposed to be proided by the \n        /// publisher of a document to tyhe consumer of a document. \n        /// </summary>\n        public PublishLicense(string signedPublishLicense)\n        {\n\n            ArgumentNullException.ThrowIfNull(signedPublishLicense);\n\n            _serializedPublishLicense = signedPublishLicense;\n\n            /////////////////\n            // parse out the Use License acquisition Url \n            /////////////////\n            _useLicenseAcquisitionUriFromPublishLicense =\n                    ClientSession.GetUseLicenseAcquisitionUriFromPublishLicense(_serializedPublishLicense);\n\n            if (_useLicenseAcquisitionUriFromPublishLicense == null)\n            {\n                throw new RightsManagementException(RightsManagementFailureCode.InvalidLicense);\n            }\n\n\n            /////////////////\n            // parse out the Content Id GUID \n            /////////////////\n            String contentIdStr = ClientSession.GetContentIdFromPublishLicense(_serializedPublishLicense);\n\n            if (contentIdStr == null)\n            {\n                throw new RightsManagementException(RightsManagementFailureCode.InvalidLicense);                \n            }\n            else\n            {\n                _contentId = new Guid(contentIdStr);\n            }\n\n            /////////////////","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Security/RightsManagement/PublishLicense.cs#L18-L54","documentation":"The PublishLicense(string) constructor parses a serialized signed publish license and requires a valid Use License acquisition URI inside it. When the underlying RM SDK (msdrm) cannot extract the acquisition URI from the license blob, the constructor throws RightsManagementException with FailureCode.InvalidLicense, meaning the license string is malformed, truncated, or not a genuinely signed publish license.","triggerScenarios":"Calling new PublishLicense(serialized) where the string was corrupted in transit/storage, was never produced by UnsignedPublishLicense.Sign, contains extra whitespace/encoding changes (e.g. XML-escaped or line-wrapped), or is a Use License passed in by mistake instead of a Publish License.","commonSituations":"Storing the license in a database/config and losing characters to encoding; copying the license out of an XPS/protected document incorrectly; hand-editing the XML; mixing up UseLicense and PublishLicense strings when persisting both.","solutions":["Verify the string is the exact output of UnsignedPublishLicense.Sign (or the publisher's original) with no re-encoding or trimming","Confirm the string is a publish license, not a use license — use UseLicense for the use-license blob","Round-trip test: new PublishLicense(new UnsignedPublishLicense(...).Sign(secureEnvironment).ToString()) to confirm the blob itself is valid","Inspect the license XML: it must contain the Work/OFFICIAL resource with a valid use-license-acquisition-url element"],"exampleFix":"// before\nvar publishLicense = new PublishLicense(config.AppSettings[\"License\"]);\n\n// after\nstring raw = config.AppSettings[\"License\"];\nif (string.IsNullOrWhiteSpace(raw) || !raw.Contains(\"<WORK\"))\n    throw new InvalidOperationException(\"Stored publish license is missing or malformed\");\nvar publishLicense = new PublishLicense(raw);","handlingStrategy":"validation","validationCode":"if (string.IsNullOrWhiteSpace(signedPublishLicense))\n    throw new ArgumentException(\"Publish license string is empty\", nameof(signedPublishLicense));\n// the signed publish license is XML; a valid one embeds an acquisition URL\nif (!signedPublishLicense.Contains(\"use-license-acquisition-url\"))\n    throw new InvalidDataException(\"License has no use-license acquisition URL; not a valid signed publish license\");","typeGuard":"static bool IsValidPublishLicense(string s) =>\n    !string.IsNullOrWhiteSpace(s) && s.TrimStart().StartsWith(\"<\") && s.Contains(\"use-license-acquisition-url\");","tryCatchPattern":"try { var pl = new PublishLicense(serialized); }\ncatch (RightsManagementException ex) when (ex.FailureCode == RightsManagementFailureCode.InvalidLicense)\n{\n    // re-obtain or re-sign the license; do not retry the same blob\n    logger.LogError(ex, \"Publish license blob is invalid\");\n    throw new InvalidLicenseException(\"Publish license malformed — republish the document\", ex);\n}","preventionTips":["Persist the license exactly as returned by UnsignedPublishLicense.Sign — no re-encoding, trimming, or XML escaping","Store licenses as opaque blobs (e.g. base64 of UTF-8) with a length/hash to detect truncation","Never hand-edit or regenerate license XML text","Keep publish licenses and use licenses in clearly separate fields"],"tags":["rights-management","drm","license-parsing","wpf"],"backgroundTag":"schema-validation-failed","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}