diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx
index 6936f16a6501240063f90c332fc8108dc1faeaa1_ZnJvbnRlbmQvc3JjL2FwcC9wYWdlLnRzeA==..ff76e62386781f63689a85cfba351307bcf9a848_ZnJvbnRlbmQvc3JjL2FwcC9wYWdlLnRzeA== 100644
--- a/frontend/src/app/page.tsx
+++ b/frontend/src/app/page.tsx
@@ -19,6 +19,7 @@
   deleteProject,
   updateProjectState,
 } from "@/api/cubicweb";
+import { useHandleAuthErrors } from "@/hooks/useHandleAuthErrors";
 
 export default function Home() {
   const { data: projects, loading: projectsLoading } = useGetProjectList();
@@ -31,6 +32,7 @@
     eid?: number;
     type?: "deleteDataService" | "deleteProject" | "toggle";
   }>({ visible: false });
+  const handleAuthErrors = useHandleAuthErrors();
 
   return (
     <Container>
@@ -130,9 +132,23 @@
         text={modal?.text ?? ""}
         onClose={() => setModal((prev) => ({ ...prev, visible: false }))}
         onAccept={async () => {
-          if (modal.type === "toggle") {
-            const project = projects?.find((p) => p.eid === modal.eid);
-            if (project && modal.eid) {
-              await updateProjectState(modal.eid, !project.activated);
-              project.activated = !project.activated;
+          try {
+            if (modal.type === "toggle") {
+              const project = projects?.find((p) => p.eid === modal.eid);
+              if (project && modal.eid) {
+                await updateProjectState(modal.eid, !project.activated);
+                project.activated = !project.activated;
+              }
+            } else if (modal.type === "deleteProject" && modal.eid) {
+              await deleteProject(modal.eid);
+              projects?.splice(
+                projects?.findIndex((p) => p.eid === modal.eid),
+                1,
+              );
+            } else if (modal.type === "deleteDataService" && modal.eid) {
+              await deleteDataService(modal.eid);
+              dataServices?.splice(
+                dataServices?.findIndex((p) => p.eid === modal.eid),
+                1,
+              );
             }
@@ -138,16 +154,6 @@
             }
-          } else if (modal.type === "deleteProject" && modal.eid) {
-            await deleteProject(modal.eid);
-            projects?.splice(
-              projects?.findIndex((p) => p.eid === modal.eid),
-              1,
-            );
-          } else if (modal.type === "deleteDataService" && modal.eid) {
-            await deleteDataService(modal.eid);
-            dataServices?.splice(
-              dataServices?.findIndex((p) => p.eid === modal.eid),
-              1,
-            );
+          } catch (e) {
+            handleAuthErrors(e);
           }
         }}
       />
diff --git a/frontend/src/components/DataServiceForm.tsx b/frontend/src/components/DataServiceForm.tsx
index 6936f16a6501240063f90c332fc8108dc1faeaa1_ZnJvbnRlbmQvc3JjL2NvbXBvbmVudHMvRGF0YVNlcnZpY2VGb3JtLnRzeA==..ff76e62386781f63689a85cfba351307bcf9a848_ZnJvbnRlbmQvc3JjL2NvbXBvbmVudHMvRGF0YVNlcnZpY2VGb3JtLnRzeA== 100644
--- a/frontend/src/components/DataServiceForm.tsx
+++ b/frontend/src/components/DataServiceForm.tsx
@@ -15,6 +15,7 @@
 import { useRouter } from "next/navigation";
 import { createDataService, updateDataService } from "@/api/cubicweb";
 import { LoadingButton } from "@mui/lab";
+import { useHandleAuthErrors } from "@/hooks/useHandleAuthErrors";
 
 export interface DataServiceFormProps {
   dataService?: DataService;
@@ -29,8 +30,9 @@
           refresh_period: "weekly",
         },
   });
+  const handleAuthErrors = useHandleAuthErrors();
 
   const router = useRouter();
 
   const onSubmit: SubmitHandler<DataService> = async (data) => {
     setLoading(true);
@@ -32,16 +34,20 @@
 
   const router = useRouter();
 
   const onSubmit: SubmitHandler<DataService> = async (data) => {
     setLoading(true);
-    if (data.eid === undefined) {
-      const result = await createDataService(data);
-      const eid = result[0][0];
-      setLoading(false);
-      router.push(`/data-service/${eid}`);
-    } else {
-      await updateDataService(data);
-      setLoading(false);
+    try {
+      if (data.eid === undefined) {
+        const result = await createDataService(data);
+        const eid = result[0][0];
+        setLoading(false);
+        router.push(`/data-service/${eid}`);
+      } else {
+        await updateDataService(data);
+        setLoading(false);
+      }
+    } catch (e) {
+      handleAuthErrors(e);
     }
   };
 
diff --git a/frontend/src/components/ProjectForm.tsx b/frontend/src/components/ProjectForm.tsx
index 6936f16a6501240063f90c332fc8108dc1faeaa1_ZnJvbnRlbmQvc3JjL2NvbXBvbmVudHMvUHJvamVjdEZvcm0udHN4..ff76e62386781f63689a85cfba351307bcf9a848_ZnJvbnRlbmQvc3JjL2NvbXBvbmVudHMvUHJvamVjdEZvcm0udHN4 100644
--- a/frontend/src/components/ProjectForm.tsx
+++ b/frontend/src/components/ProjectForm.tsx
@@ -14,6 +14,7 @@
 import { useRouter } from "next/navigation";
 import { LoadingButton } from "@mui/lab";
 import { createProject, updateProject } from "@/api/cubicweb";
+import { useHandleAuthErrors } from "@/hooks/useHandleAuthErrors";
 
 export interface ProjectFormProps {
   project?: Project;
@@ -24,8 +25,9 @@
   const { handleSubmit, control } = useForm<Project>({
     defaultValues: project,
   });
+  const handleAuthErrors = useHandleAuthErrors();
 
   const router = useRouter();
 
   const onSubmit: SubmitHandler<Project> = async (data) => {
     setLoading(true);
@@ -27,16 +29,20 @@
 
   const router = useRouter();
 
   const onSubmit: SubmitHandler<Project> = async (data) => {
     setLoading(true);
-    if (data.eid === undefined) {
-      const result = await createProject(data);
-      const eid = result[0][0];
-      setLoading(false);
-      router.push(`/project/${eid}`);
-    } else {
-      await updateProject(data);
-      setLoading(false);
+    try {
+      if (data.eid === undefined) {
+        const result = await createProject(data);
+        const eid = result[0][0];
+        setLoading(false);
+        router.push(`/project/${eid}`);
+      } else {
+        await updateProject(data);
+        setLoading(false);
+      }
+    } catch (e) {
+      handleAuthErrors(e);
     }
   };
 
diff --git a/frontend/src/hooks/useGetDataService.tsx b/frontend/src/hooks/useGetDataService.tsx
index 6936f16a6501240063f90c332fc8108dc1faeaa1_ZnJvbnRlbmQvc3JjL2hvb2tzL3VzZUdldERhdGFTZXJ2aWNlLnRzeA==..ff76e62386781f63689a85cfba351307bcf9a848_ZnJvbnRlbmQvc3JjL2hvb2tzL3VzZUdldERhdGFTZXJ2aWNlLnRzeA== 100644
--- a/frontend/src/hooks/useGetDataService.tsx
+++ b/frontend/src/hooks/useGetDataService.tsx
@@ -1,8 +1,9 @@
 import { UnknownEidError, getDataService } from "@/api/cubicweb";
 import { DataService } from "@/types";
 import { useState, useEffect } from "react";
+import { useHandleAuthErrors } from "./useHandleAuthErrors";
 
 export function useGetDataService(eid: number) {
   const [loading, setLoading] = useState(true);
   const [data, setData] = useState<DataService | undefined>(undefined);
   const [error, setError] = useState<string | undefined>();
@@ -4,8 +5,9 @@
 
 export function useGetDataService(eid: number) {
   const [loading, setLoading] = useState(true);
   const [data, setData] = useState<DataService | undefined>(undefined);
   const [error, setError] = useState<string | undefined>();
+  const handleAuthErrors = useHandleAuthErrors();
 
   useEffect(() => {
     setLoading(true);
@@ -16,6 +18,7 @@
           setLoading(false);
           setData(result);
         })
+        .catch(handleAuthErrors)
         .catch((e) => {
           if (e instanceof UnknownEidError) {
             setError(`Impossible de trouver le data service '${eid}'`);
@@ -24,6 +27,6 @@
           }
         });
     }
-  }, [eid]);
+  }, [eid, handleAuthErrors]);
   return { loading, data, error };
 }
diff --git a/frontend/src/hooks/useGetDataServiceList.tsx b/frontend/src/hooks/useGetDataServiceList.tsx
index 6936f16a6501240063f90c332fc8108dc1faeaa1_ZnJvbnRlbmQvc3JjL2hvb2tzL3VzZUdldERhdGFTZXJ2aWNlTGlzdC50c3g=..ff76e62386781f63689a85cfba351307bcf9a848_ZnJvbnRlbmQvc3JjL2hvb2tzL3VzZUdldERhdGFTZXJ2aWNlTGlzdC50c3g= 100644
--- a/frontend/src/hooks/useGetDataServiceList.tsx
+++ b/frontend/src/hooks/useGetDataServiceList.tsx
@@ -1,7 +1,8 @@
 import { getDataServiceList } from "@/api/cubicweb";
 import { DataService } from "@/types";
 import { useEffect, useState } from "react";
+import { useHandleAuthErrors } from "./useHandleAuthErrors";
 
 export function useGetDataServiceList() {
   const [loading, setLoading] = useState(true);
   const [data, setData] = useState<Array<DataService> | undefined>(undefined);
@@ -4,7 +5,8 @@
 
 export function useGetDataServiceList() {
   const [loading, setLoading] = useState(true);
   const [data, setData] = useState<Array<DataService> | undefined>(undefined);
+  const handleAuthErrors = useHandleAuthErrors();
 
   useEffect(() => {
     setLoading(true);
@@ -8,11 +10,13 @@
 
   useEffect(() => {
     setLoading(true);
-    getDataServiceList().then((result) => {
-      console.log(result);
-      setLoading(false);
-      setData(result);
-    });
-  }, []);
+    getDataServiceList()
+      .then((result) => {
+        console.log(result);
+        setLoading(false);
+        setData(result);
+      })
+      .catch(handleAuthErrors);
+  }, [handleAuthErrors]);
   return { loading, data };
 }
diff --git a/frontend/src/hooks/useGetProject.tsx b/frontend/src/hooks/useGetProject.tsx
index 6936f16a6501240063f90c332fc8108dc1faeaa1_ZnJvbnRlbmQvc3JjL2hvb2tzL3VzZUdldFByb2plY3QudHN4..ff76e62386781f63689a85cfba351307bcf9a848_ZnJvbnRlbmQvc3JjL2hvb2tzL3VzZUdldFByb2plY3QudHN4 100644
--- a/frontend/src/hooks/useGetProject.tsx
+++ b/frontend/src/hooks/useGetProject.tsx
@@ -1,8 +1,9 @@
 import { UnknownEidError, getProject } from "@/api/cubicweb";
 import { Project } from "@/types";
 import { useState, useEffect } from "react";
+import { useHandleAuthErrors } from "./useHandleAuthErrors";
 
 export function useGetProject(eid: number) {
   const [loading, setLoading] = useState(true);
   const [data, setData] = useState<Project | undefined>();
   const [error, setError] = useState<string | undefined>();
@@ -4,8 +5,9 @@
 
 export function useGetProject(eid: number) {
   const [loading, setLoading] = useState(true);
   const [data, setData] = useState<Project | undefined>();
   const [error, setError] = useState<string | undefined>();
+  const handleAuthErrors = useHandleAuthErrors();
 
   useEffect(() => {
     setLoading(true);
@@ -16,6 +18,7 @@
           setLoading(false);
           setData(result);
         })
+        .catch(handleAuthErrors)
         .catch((e) => {
           if (e instanceof UnknownEidError) {
             setError(`Impossible de trouver le projet '${eid}'`);
@@ -24,6 +27,6 @@
           }
         });
     }
-  }, [eid]);
+  }, [eid, handleAuthErrors]);
   return { loading, data, error };
 }
diff --git a/frontend/src/hooks/useGetProjectList.tsx b/frontend/src/hooks/useGetProjectList.tsx
index 6936f16a6501240063f90c332fc8108dc1faeaa1_ZnJvbnRlbmQvc3JjL2hvb2tzL3VzZUdldFByb2plY3RMaXN0LnRzeA==..ff76e62386781f63689a85cfba351307bcf9a848_ZnJvbnRlbmQvc3JjL2hvb2tzL3VzZUdldFByb2plY3RMaXN0LnRzeA== 100644
--- a/frontend/src/hooks/useGetProjectList.tsx
+++ b/frontend/src/hooks/useGetProjectList.tsx
@@ -1,7 +1,8 @@
 import { getProjectList } from "@/api/cubicweb";
 import { Project } from "@/types";
 import { useState, useEffect } from "react";
+import { useHandleAuthErrors } from "./useHandleAuthErrors";
 
 export function useGetProjectList() {
   const [loading, setLoading] = useState(true);
   const [data, setData] = useState<Array<Project> | undefined>(undefined);
@@ -4,7 +5,8 @@
 
 export function useGetProjectList() {
   const [loading, setLoading] = useState(true);
   const [data, setData] = useState<Array<Project> | undefined>(undefined);
+  const handleAuthErrors = useHandleAuthErrors();
 
   useEffect(() => {
     setLoading(true);
@@ -8,11 +10,13 @@
 
   useEffect(() => {
     setLoading(true);
-    getProjectList().then((result) => {
-      console.log(result);
-      setLoading(false);
-      setData(result);
-    });
-  }, []);
+    getProjectList()
+      .then((result) => {
+        console.log(result);
+        setLoading(false);
+        setData(result);
+      })
+      .catch(handleAuthErrors);
+  }, [handleAuthErrors]);
   return { loading, data };
 }
diff --git a/frontend/src/hooks/useHandleAuthErrors.tsx b/frontend/src/hooks/useHandleAuthErrors.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..ff76e62386781f63689a85cfba351307bcf9a848_ZnJvbnRlbmQvc3JjL2hvb2tzL3VzZUhhbmRsZUF1dGhFcnJvcnMudHN4
--- /dev/null
+++ b/frontend/src/hooks/useHandleAuthErrors.tsx
@@ -0,0 +1,24 @@
+import { useLogout } from "@/api/cubicweb";
+import { useMemo } from "react";
+
+export function useHandleAuthErrors() {
+  const logout = useLogout();
+
+  const handleAuthErrors = useMemo(() => {
+    return (e: unknown) => {
+      if (
+        e &&
+        typeof e === "object" &&
+        "title" in e &&
+        e.title === "AuthenticationError"
+      ) {
+        logout();
+      } else {
+        throw e;
+      }
+    };
+    // eslint-disable-next-line react-hooks/exhaustive-deps
+  }, []);
+
+  return handleAuthErrors;
+}