siyuan-note/siyuan · error

CardDAV: address file extension name is invalid

Error message

CardDAV: address file extension name is invalid

What it means

Sentinel error ErrorCardDavAddressFileExtensionNameInvalid, thrown when a CardDAV address object resource path does not end with the expected .vcf extension. The CardDAV handler enforces this before any disk read/write to prevent arbitrary file access inside the address book directory. Like the other CardDAV sentinels it is a package-level var meant for errors.Is comparison.

Source

Thrown at kernel/model/carddav.go:97

		Description:          "Default address book",
		MaxResourceSize:      addressBookMaxResourceSize,
		SupportedAddressData: addressBookSupportedAddressData,
	}
	contacts = Contacts{
		loaded:        false,
		changed:       false,
		lock:          sync.Mutex{},
		books:         sync.Map{},
		booksMetaData: []*carddav.AddressBook{},
	}

	ErrorCardDavPathInvalid = errors.New("CardDAV: path is invalid")

	ErrorCardDavBookNotFound    = errors.New("CardDAV: address book not found")
	ErrorCardDavBookPathInvalid = errors.New("CardDAV: address book path is invalid")

	ErrorCardDavAddressNotFound                 = errors.New("CardDAV: address not found")
	ErrorCardDavAddressFileExtensionNameInvalid = errors.New("CardDAV: address file extension name is invalid")
)

// ImportAddressBook imports an address book from a vCard file (*.vcf)
func ImportAddressBook(addressBookPath, cardContent string) (addresses []*AddressObject, err error) {
	// TODO: Check whether the path is valid (PathDepth: Address)
	// TODO: Check whether the address book exists
	// TODO: Decode the card content
	// TODO: Save the cards to the file system
	return
}

// ExportAddressBook exports an address book to a vCard file (*.vcf)
func ExportAddressBook(addressBookPath string) (cardContent string, err error) {
	// TODO: Check whether the path is valid (PathDepth: AddressBook)
	// TODO: Check whether the address book exists
	// TODO: Encode the card content
	return
}

View on GitHub (pinned to 251596fc0d)

Solutions

  1. Ensure every address object URL ends with .vcf (lowercase) before issuing PUT/GET requests.
  2. Strip query strings and fragments from the resource path client-side before sending.
  3. If migrating data, convert all address files to valid vCard 3.0/4.0 .vcf files first.
  4. Validate the extension programmatically in the client before contacting the server.

Example fix

// before
path := fmt.Sprintf("/default/%s", id) // missing extension

// after
if !strings.HasSuffix(path, ".vcf") {
    path += ".vcf"
}
Defensive patterns

Strategy: validation

Validate before calling

// Ensure .vcf extension before any CardDAV address-object request
func ensureVcfExt(p string) string {
    p = strings.SplitN(p, "?", 2)[0]
    if !strings.HasSuffix(strings.ToLower(p), ".vcf") {
        p += ".vcf"
    }
    return p
}

Type guard

func isVcfPath(p string) bool {
    p = strings.SplitN(p, "?", 2)[0]
    return strings.HasSuffix(strings.ToLower(p), ".vcf")
}

Try / catch

if strings.Contains(err.Error(), "address file extension name is invalid") { fixExtensionAndRetry() }

Prevention

When it happens

Trigger: A PUT or GET to an address book path whose final segment uses a non-.vcf extension (e.g. .json, .txt, no extension), or a path containing a query string that confuses extension extraction. Also triggered by malformed client requests that POST to a collection URL with the wrong suffix.

Common situations: A custom CardDAV client or integration script writes contacts with the wrong file extension; a migration tool imported contacts as .json; a client appends cache-busting query parameters that become part of the perceived extension.

Related errors


AI-assisted analysis of siyuan-note/siyuan@251596fc0d (2026-08-12). Data as JSON: /api/errors/d086b9f39ca1542d. Report an issue: GitHub.