Dolibarr/dolibarr · warning

ErrorFileNotFoundWithSharedLink

Error message

ErrorFileNotFoundWithSharedLink

What it means

When a shared link (hashp) is used, viewimage.php looks up the EcmFiles record and related permissions; if the file referenced by the shared hash cannot be found (or the shared-link branch fails to resolve a file), it calls httponly_accessforbidden('ErrorFileNotFoundWithSharedLink', 403, 1). The message is deliberately generic to avoid leaking file existence.

Solutions

  1. Regenerate the shared link (recompute hashp from the current file record)
  2. Verify a row exists in llx_ecm_files with that hashp for the correct entity
  3. Recreate the missing ecm_files record if the file exists on disk (ECM module rescan / fix tool)
  4. Check multicompany entity configuration matches where the share was created

Example fix

// before
$hashp = substr($knownhash, 0, 16); // truncated
// after
include_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmfiles.class.php';
$ecmfile = new EcmFiles($db);
$ecmfile->fetch(0, '', $relpath);
$hashp = $ecmfile->hashp;
Defensive patterns

Strategy: fallback

Validate before calling

$ecmfile = new EcmFiles($db);
if ($ecmfile->fetch(0, '', '', $hashp) <= 0) { $this->errors[] = 'Shared link invalid'; }

Try / catch

if ($ecmfile->fetch(0, '', '', $hashp) <= 0) {
    http_response_code(404);
    exit('Shared link no longer valid');
}

Prevention

When it happens

Trigger: GET viewimage.php?hashp=<hash> where the hash does not match any llx_ecm_files row (deleted file, wrong hash, expired/rotated share, different entity), causing the $ecmfile fetch/verification inside the hashp branch to fail.

Common situations: Recipients opening an old shared link after the file was deleted or moved; database restores losing ecm_files rows; multicompany entity mismatch between share creation and access; truncated hashp values in copied URLs.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of Dolibarr/dolibarr@598aa4bdad (2026-09-14). Data as JSON: /api/errors/af9fe6f635330657. Report an issue: GitHub.

Appendix: source

Thrown at htdocs/viewimage.php:245

		if ($modulepart) {	// Not required, so often not defined, for link using public hashp parameter.
			if ($moduleparttocheck == $modulepart) {
				// We remove first level of directory
				$original_file = (($tmp[1] ? $tmp[1].'/' : '').$ecmfile->filename); // this is relative to module dir
				//var_dump($original_file); exit;
			} else {
				httponly_accessforbidden('Bad link. File is from another module part.', 403);
			}
		} else {
			$modulepart = $moduleparttocheck;
			$original_file = (($tmp[1] ? $tmp[1].'/' : '').$ecmfile->filename); // this is relative to module dir
		}

		if ($extname) {
			$original_file = getImageFileNameForSize($original_file, $extname);
		}
	} else {
		httponly_accessforbidden("ErrorFileNotFoundWithSharedLink", 403, 1);
	}
}

// Define mime type
$type = 'application/octet-stream';
if (GETPOST('type', 'alpha')) {
	$type = GETPOST('type', 'alpha');
} else {
	$type = dol_mimetype($original_file);
}

// Security: This wrapper is for images. We do not allow type/html
if (preg_match('/html/i', $type)) {
	httponly_accessforbidden('Error: Using the image wrapper to output a file with a mime type HTML is not possible.');
}
// Security: This wrapper is for images. We do not allow files ending with .noexe
if (preg_match('/\.noexe$/i', $original_file)) {
	httponly_accessforbidden('Error: Using the image wrapper to output a file ending with .noexe is not allowed.');

View on GitHub (pinned to 598aa4bdad)