diff --git a/src/main/java/de/ozgcloud/admin/RootModelAssembler.java b/src/main/java/de/ozgcloud/admin/RootModelAssembler.java
index b8db6e7eb5b23571f40ae99be833bdddd935dcc0..2cf01448f6fa1ab4f52d3a72fc06b15d57c5cda7 100644
--- a/src/main/java/de/ozgcloud/admin/RootModelAssembler.java
+++ b/src/main/java/de/ozgcloud/admin/RootModelAssembler.java
@@ -28,12 +28,10 @@ import org.springframework.hateoas.server.RepresentationModelAssembler;
 import org.springframework.hateoas.server.mvc.WebMvcLinkBuilder;
 import org.springframework.stereotype.Component;
 
-import io.micrometer.common.lang.NonNullApi;
 import lombok.RequiredArgsConstructor;
 
 @Component
 @RequiredArgsConstructor
-@NonNullApi
 public class RootModelAssembler implements RepresentationModelAssembler<Root, EntityModel<Root>> {
 	static final String REL_CONFIGURATION = "configuration";
 
diff --git a/src/main/java/de/ozgcloud/admin/errorhandling/AdminExceptionHandler.java b/src/main/java/de/ozgcloud/admin/common/errorhandling/ExceptionController.java
similarity index 95%
rename from src/main/java/de/ozgcloud/admin/errorhandling/AdminExceptionHandler.java
rename to src/main/java/de/ozgcloud/admin/common/errorhandling/ExceptionController.java
index 27f9c626b4586717558355e5a2671676ec0e570d..75a3dda5ce10f4d50ebaaabc31ec840ac9c54d3b 100644
--- a/src/main/java/de/ozgcloud/admin/errorhandling/AdminExceptionHandler.java
+++ b/src/main/java/de/ozgcloud/admin/common/errorhandling/ExceptionController.java
@@ -19,7 +19,7 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-package de.ozgcloud.admin.errorhandling;
+package de.ozgcloud.admin.common.errorhandling;
 
 import java.util.Map;
 
@@ -36,7 +36,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExcep
 import de.ozgcloud.common.errorhandling.TechnicalException;
 
 @RestControllerAdvice
-public class AdminExceptionHandler extends ResponseEntityExceptionHandler {
+public class ExceptionController extends ResponseEntityExceptionHandler {
 
 	static final Map<Class<? extends Exception>, HttpStatus> STATUS_BY_EXCEPTION = Map.of(
 			RuntimeException.class, HttpStatus.INTERNAL_SERVER_ERROR,
diff --git a/src/main/java/de/ozgcloud/admin/errorhandling/FunctionalException.java b/src/main/java/de/ozgcloud/admin/common/errorhandling/FunctionalException.java
similarity index 97%
rename from src/main/java/de/ozgcloud/admin/errorhandling/FunctionalException.java
rename to src/main/java/de/ozgcloud/admin/common/errorhandling/FunctionalException.java
index e0e57b3feb65073674c0645aac9fc997af8dbfed..5b2369b2a97772a1607b84ebaa9a46de2fec9643 100644
--- a/src/main/java/de/ozgcloud/admin/errorhandling/FunctionalException.java
+++ b/src/main/java/de/ozgcloud/admin/common/errorhandling/FunctionalException.java
@@ -19,7 +19,7 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-package de.ozgcloud.admin.errorhandling;
+package de.ozgcloud.admin.common.errorhandling;
 
 import java.io.Serial;
 import java.util.UUID;
diff --git a/src/main/java/de/ozgcloud/admin/environment/FrontendEnvironmentController.java b/src/main/java/de/ozgcloud/admin/environment/FrontendEnvironmentController.java
index b61f1d9c358751a1e974be75b9cc33b3f2551536..7f58244eddd973d568eb271fbc59d2b551c849f0 100644
--- a/src/main/java/de/ozgcloud/admin/environment/FrontendEnvironmentController.java
+++ b/src/main/java/de/ozgcloud/admin/environment/FrontendEnvironmentController.java
@@ -14,7 +14,7 @@ import lombok.RequiredArgsConstructor;
 @RequestMapping(FrontendEnvironmentController.PATH)
 public class FrontendEnvironmentController {
 
-	static final String PATH = "/api/environment"; // NOSONAR
+	static final String PATH = "/api/frontendEnvironment"; // NOSONAR
 
 	private final ProductionProperties environmentProperties;
 
diff --git a/src/main/java/de/ozgcloud/admin/security/SecurityConfiguration.java b/src/main/java/de/ozgcloud/admin/security/SecurityConfiguration.java
index 568d79a76fc6268d93b7ecc2e172ae9625d40ed1..03de09a7d58f57bd20200d7ea468391b5c3e572f 100644
--- a/src/main/java/de/ozgcloud/admin/security/SecurityConfiguration.java
+++ b/src/main/java/de/ozgcloud/admin/security/SecurityConfiguration.java
@@ -53,7 +53,7 @@ public class SecurityConfiguration {
 		http.exceptionHandling(eh -> eh.authenticationEntryPoint(authenticationEntryPoint));
 
 		http.authorizeHttpRequests(requests -> requests
-				.requestMatchers(HttpMethod.GET, "/api/environment").permitAll()
+				.requestMatchers(HttpMethod.GET, "/api/frontendEnvironment").permitAll()
 				.requestMatchers("/api").authenticated()
 				.requestMatchers("/api/**").authenticated()
 				.requestMatchers("/actuator").permitAll()
diff --git a/src/test/java/de/ozgcloud/admin/errorhandling/AdminExceptionHandlerITCase.java b/src/test/java/de/ozgcloud/admin/common/errorhandling/ExceptionControllerITCase.java
similarity index 63%
rename from src/test/java/de/ozgcloud/admin/errorhandling/AdminExceptionHandlerITCase.java
rename to src/test/java/de/ozgcloud/admin/common/errorhandling/ExceptionControllerITCase.java
index 740d33c05999c8ee00d6135e636bb20aa2d12493..b4884dd0e4b23e908645251677c76064c9086e8a 100644
--- a/src/test/java/de/ozgcloud/admin/errorhandling/AdminExceptionHandlerITCase.java
+++ b/src/test/java/de/ozgcloud/admin/common/errorhandling/ExceptionControllerITCase.java
@@ -1,12 +1,19 @@
-package de.ozgcloud.admin.errorhandling;
+package de.ozgcloud.admin.common.errorhandling;
 
 import static org.mockito.ArgumentMatchers.*;
 import static org.mockito.Mockito.*;
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
 
+import java.util.Set;
 import java.util.stream.Stream;
 
+import jakarta.validation.ConstraintViolation;
+import jakarta.validation.ConstraintViolationException;
+import jakarta.validation.Validation;
+import jakarta.validation.Validator;
+import jakarta.validation.constraints.NotEmpty;
+
 import org.junit.jupiter.api.Nested;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
@@ -23,12 +30,14 @@ import org.springframework.test.web.servlet.ResultActions;
 import de.ozgcloud.admin.RootController;
 import de.ozgcloud.admin.RootModelAssembler;
 import de.ozgcloud.common.test.ITCase;
+import lombok.Builder;
+import lombok.Getter;
 import lombok.SneakyThrows;
 
 @ITCase
 @AutoConfigureMockMvc
 @WithMockUser
-public class AdminExceptionHandlerITCase {
+class ExceptionControllerITCase {
 
 	@Autowired
 	private MockMvc mockMvc;
@@ -46,23 +55,9 @@ public class AdminExceptionHandlerITCase {
 
 			var result = performGet();
 
-			System.out.println(result.andReturn().getResponse().getContentAsString());
-
 			result.andExpect(status().is(expectedStatus.value()));
 		}
 
-		@Test
-		@SneakyThrows
-		void shouldHandleRuntimeExceptionExceptionWithStatus() {
-			when(modelAssembler.toModel(any())).thenThrow(new RuntimeException("Message"));
-
-			var result = performGet();
-
-			System.out.println(result.andReturn().getResponse().getContentAsString());
-
-			result.andExpect(status().isInternalServerError());
-		}
-
 		@ParameterizedTest
 		@MethodSource("exceptionAndExpectedStatus")
 		@SneakyThrows
@@ -75,13 +70,42 @@ public class AdminExceptionHandlerITCase {
 		}
 
 		private static Stream<Arguments> exceptionAndExpectedStatus() {
-			return AdminExceptionHandler.STATUS_BY_EXCEPTION.entrySet().stream().map(kv -> Arguments.of(kv.getKey(), kv.getValue()));
+			return ExceptionController.STATUS_BY_EXCEPTION.entrySet().stream().map(kv -> Arguments.of(kv.getKey(), kv.getValue()));
 		}
 
+	}
+
+	@Nested
+	class TestConstraintViolationException {
+		@Test
 		@SneakyThrows
-		private ResultActions performGet() {
-			return mockMvc.perform(get(RootController.PATH));
+		void shouldHaveValidationMessage() {
+			when(modelAssembler.toModel(any())).thenAnswer((a) -> {
+				throw new ConstraintViolationException(getConstraintViolations());
+			});
+
+			var result = performGet();
+
+			result.andExpect(jsonPath("$.detail").value("string: Empty field"));
+		}
+
+		private Set<ConstraintViolation<ValidatedClass>> getConstraintViolations() {
+			Validator validator = Validation.buildDefaultValidatorFactory().getValidator();
+			return validator.validate(ValidatedClass.builder().build());
+		}
+
+		@Getter
+		@Builder
+		private static class ValidatedClass {
+			@NotEmpty(message = "Empty field")
+			private String string;
 		}
+
+	}
+
+	@SneakyThrows
+	private ResultActions performGet() {
+		return mockMvc.perform(get(RootController.PATH));
 	}
 
 }
diff --git a/src/test/java/de/ozgcloud/admin/errorhandling/AdminExceptionHandlerTest.java b/src/test/java/de/ozgcloud/admin/common/errorhandling/ExceptionControllerTest.java
similarity index 69%
rename from src/test/java/de/ozgcloud/admin/errorhandling/AdminExceptionHandlerTest.java
rename to src/test/java/de/ozgcloud/admin/common/errorhandling/ExceptionControllerTest.java
index 8f62290e40d9c31147f0497fc40330392a21dd65..f33a3715b32778a78b725e096ea0bf99e1fd4047 100644
--- a/src/test/java/de/ozgcloud/admin/errorhandling/AdminExceptionHandlerTest.java
+++ b/src/test/java/de/ozgcloud/admin/common/errorhandling/ExceptionControllerTest.java
@@ -19,9 +19,9 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-package de.ozgcloud.admin.errorhandling;
+package de.ozgcloud.admin.common.errorhandling;
 
-import static de.ozgcloud.admin.errorhandling.AdminExceptionHandler.*;
+import static de.ozgcloud.admin.common.errorhandling.ExceptionController.*;
 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
 
@@ -41,7 +41,7 @@ import org.springframework.test.web.servlet.setup.MockMvcBuilders;
 
 import lombok.SneakyThrows;
 
-class AdminExceptionHandlerTest {
+class ExceptionControllerTest {
 
 	private MockMvc mockMvc;
 
@@ -49,7 +49,7 @@ class AdminExceptionHandlerTest {
 	void setup() {
 		mockMvc = MockMvcBuilders
 				.standaloneSetup(new TestErrorController())
-				.setControllerAdvice(new AdminExceptionHandler()).build();
+				.setControllerAdvice(new ExceptionController()).build();
 	}
 
 	@DisplayName("Error handler")
@@ -74,13 +74,49 @@ class AdminExceptionHandlerTest {
 			result.andExpect(jsonPath("$.status").value(expectedStatus.value()));
 		}
 
+		@ParameterizedTest
+		@MethodSource("exceptionAndExpectedStatus")
+		@SneakyThrows
+		void shouldRespondWithTitler(Class<? extends Exception> exceptionClass, HttpStatus expectedStatus) {
+			var result = doPerformWithError(exceptionClass);
+
+			result.andExpect(jsonPath("$.title").exists());
+		}
+
+		@ParameterizedTest
+		@MethodSource("exceptionAndExpectedStatus")
+		@SneakyThrows
+		void shouldRespondWithDetail(Class<? extends Exception> exceptionClass, HttpStatus expectedStatus) {
+			var result = doPerformWithError(exceptionClass);
+
+			result.andExpect(jsonPath("$.detail").exists());
+		}
+
+		@ParameterizedTest
+		@MethodSource("exceptionAndExpectedStatus")
+		@SneakyThrows
+		void shouldRespondWithInstance(Class<? extends Exception> exceptionClass, HttpStatus expectedStatus) {
+			var result = doPerformWithError(exceptionClass);
+
+			result.andExpect(jsonPath("$.instance").exists());
+		}
+
+		@ParameterizedTest
+		@MethodSource("exceptionAndExpectedStatus")
+		@SneakyThrows
+		void shouldRespondWithType(Class<? extends Exception> exceptionClass, HttpStatus expectedStatus) {
+			var result = doPerformWithError(exceptionClass);
+
+			result.andExpect(jsonPath("$.type").exists());
+		}
+
 		private static Stream<Arguments> exceptionAndExpectedStatus() {
 			return STATUS_BY_EXCEPTION.entrySet().stream().map(kv -> Arguments.of(kv.getKey(), kv.getValue()));
 		}
 
 		@SneakyThrows
 		private ResultActions doPerformWithError(Class<? extends Exception> exceptionClass) {
-			return mockMvc.perform(get("/test-error").param("errorClassName", exceptionClass.getName()));
+			return mockMvc.perform(get("/api/test-error").param("errorClassName", exceptionClass.getName()));
 		}
 	}
 
diff --git a/src/test/java/de/ozgcloud/admin/errorhandling/TestErrorController.java b/src/test/java/de/ozgcloud/admin/common/errorhandling/TestErrorController.java
similarity index 92%
rename from src/test/java/de/ozgcloud/admin/errorhandling/TestErrorController.java
rename to src/test/java/de/ozgcloud/admin/common/errorhandling/TestErrorController.java
index 4ad218f842cdc6e96a0c3b563e51aad7c9cdbeaf..c10446041aaba51ac761ac4e91ec01d6f9b7bb4b 100644
--- a/src/test/java/de/ozgcloud/admin/errorhandling/TestErrorController.java
+++ b/src/test/java/de/ozgcloud/admin/common/errorhandling/TestErrorController.java
@@ -19,7 +19,7 @@
  * Die sprachspezifischen Genehmigungen und Beschränkungen
  * unter der Lizenz sind dem Lizenztext zu entnehmen.
  */
-package de.ozgcloud.admin.errorhandling;
+package de.ozgcloud.admin.common.errorhandling;
 
 import java.util.Collections;
 import java.util.Map;
@@ -34,11 +34,9 @@ import org.springframework.web.bind.annotation.RequestParam;
 import org.springframework.web.bind.annotation.RestController;
 
 import de.ozgcloud.common.errorhandling.TechnicalException;
-import io.micrometer.common.lang.NonNullApi;
 
 @RestController
-@RequestMapping("/test-error")
-@NonNullApi
+@RequestMapping("/api/test-error")
 class TestErrorController {
 
 	@FunctionalInterface
@@ -54,13 +52,12 @@ class TestErrorController {
 			ConstraintViolationException.class, () -> new ConstraintViolationException(ERROR_MESSAGE, Collections.emptySet()),
 			ResourceNotFoundException.class, () -> new ResourceNotFoundException(ERROR_MESSAGE),
 			FunctionalException.class, () -> new FunctionalException(() -> ERROR_MESSAGE),
-			TechnicalException.class, () -> new TechnicalException(ERROR_MESSAGE)
-	);
+			TechnicalException.class, () -> new TechnicalException(ERROR_MESSAGE));
 
 	@GetMapping
 	String throwException(@RequestParam String errorClassName) throws Exception {
 		throw EXCEPTION_PRODUCER.get(
-				Class.forName(errorClassName)
-		).produceException();
+				Class.forName(errorClassName)).produceException();
 	}
+
 }
diff --git a/src/test/java/de/ozgcloud/admin/security/SecurityConfigurationITCase.java b/src/test/java/de/ozgcloud/admin/security/SecurityConfigurationITCase.java
index 653c7b6886f24ade6257f26e718f8cc3f61f9bec..d4f087b46c68ba418bd74437e879be459f10db94 100644
--- a/src/test/java/de/ozgcloud/admin/security/SecurityConfigurationITCase.java
+++ b/src/test/java/de/ozgcloud/admin/security/SecurityConfigurationITCase.java
@@ -67,7 +67,7 @@ class SecurityConfigurationITCase {
 		@SneakyThrows
 		@ParameterizedTest
 		@ValueSource(strings = {
-				"/api/environment",
+				"/api/frontendEnvironment",
 				"/configserver/name/profile"
 		})
 		void shouldAllow(String path) {
@@ -145,7 +145,7 @@ class SecurityConfigurationITCase {
 		@SneakyThrows
 		@ParameterizedTest
 		@ValueSource(strings = {
-				"/api/environment",
+				"/api/frontendEnvironment",
 				"/configserver/name/profile",
 				"/api", "/api/configuration", "/api/configuration/param",
 		})