Dolibarr/dolibarr · error

ErrorFileNotFoundWithSharedLink

Error message

ErrorFileNotFoundWithSharedLink

What it means

When resolving a shared hash, document.php fetches the EcmFiles record by hashp; if the fetch fails (no file with that share hash, possibly after entity/multicompany switch), it loads the 'errors' lang and calls httponly_accessforbidden() with the translated ErrorFileNotFoundWithSharedLink, HTTP 403, meaning the public share link does not correspond to any existing file.

Solutions

  1. Ask the owner to re-share the file and use the fresh link
  2. Verify the file still exists and sharing is enabled in the ECM/documents area
  3. Check the share hash column (llx_ecm_files.share) is not empty and matches the URL
  4. In multicompany setups confirm the correct entity is served for public links

Example fix

// before (revoked share)
document.php?hashp=revokedhash
// after: owner re-enables sharing, then use the new hash
document.php?hashp=<newly generated share hash>
Defensive patterns

Strategy: fallback

Validate before calling

$ecm = new EcmFiles($db);
if ($ecm->fetch(0,'','','',$hashp) <= 0) {
  // show 'link expired' page instead of proceeding
}

Try / catch

try { if ($ecmfile->fetch(0,'','','',$hashp) <= 0) throw new Exception('not found'); } catch (Exception $e) { render_share_expired_page(); }

Prevention

When it happens

Trigger: document.php?hashp=<value> where $ecmfile->fetch(0,'','','',$hashp) returns <=0: hash revoked (share removed sets share column empty), hash mistyped/truncated, wrong entity in multicompany, or file deleted.

Common situations: Recipients using an old share link after the owner revoked sharing; files deleted or moved in ECM; multicompany entity mismatch between link generation and access; email clients breaking the long hash into lines.

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


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

Appendix: source

Thrown at htdocs/document.php:247

			}

			$entity = $ecmfile->entity;
			if (isModEnabled('multicompany') && !empty($ecmfile->src_object_type) && $ecmfile->src_object_id > 0) {
				$object = fetchObjectByElement($ecmfile->src_object_id, $ecmfile->src_object_type);
				if (is_object($object) && $object->id > 0) {
					$entity = $object->entity;
				}
			}

			if ($entity != $conf->entity) {
				$conf->entity = $entity;
				$conf->setValues($db);
				// Multicompany: Here we are switching entity and later we will check the requested object is in this entity but may be that user is not allowed to log/see entity
				// but we don't mind, we are using the public hash to get file.
			}
		} else {
			$langs->load("errors");
			httponly_accessforbidden($langs->trans("ErrorFileNotFoundWithSharedLink"), 403, 1);
		}
	}
}

// Define attachment (attachment=true to force choice popup 'open'/'save as')
$attachment = true;
if (preg_match('/\.(html|htm)$/i', $original_file)) {
	$attachment = false;
}
if (isset($_GET["attachment"])) {
	$attachment = GETPOST("attachment", 'alpha') ? true : false;
}
if (getDolGlobalString('MAIN_DISABLE_FORCE_SAVEAS')) {
	$attachment = false;
}

// Define mime type
$type = 'application/octet-stream'; // By default

View on GitHub (pinned to 598aa4bdad)