diff --git a/auto-configurations/common/spring-ai-autoconfigure-retry/src/main/java/org/springframework/ai/retry/autoconfigure/SpringAiRetryAutoConfiguration.java b/auto-configurations/common/spring-ai-autoconfigure-retry/src/main/java/org/springframework/ai/retry/autoconfigure/SpringAiRetryAutoConfiguration.java
index 36d212c8d8a..27cdda30839 100644
--- a/auto-configurations/common/spring-ai-autoconfigure-retry/src/main/java/org/springframework/ai/retry/autoconfigure/SpringAiRetryAutoConfiguration.java
+++ b/auto-configurations/common/spring-ai-autoconfigure-retry/src/main/java/org/springframework/ai/retry/autoconfigure/SpringAiRetryAutoConfiguration.java
@@ -17,6 +17,7 @@
 package org.springframework.ai.retry.autoconfigure;
 
 import java.io.IOException;
+import java.net.URI;
 import java.nio.charset.StandardCharsets;
 
 import org.slf4j.Logger;
@@ -30,6 +31,7 @@
 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import org.springframework.boot.context.properties.EnableConfigurationProperties;
 import org.springframework.context.annotation.Bean;
+import org.springframework.http.HttpMethod;
 import org.springframework.http.client.ClientHttpResponse;
 import org.springframework.lang.NonNull;
 import org.springframework.retry.RetryCallback;
@@ -87,7 +89,8 @@ public boolean hasError(@NonNull ClientHttpResponse response) throws IOException
 			}
 
 			@Override
-			public void handleError(@NonNull ClientHttpResponse response) throws IOException {
+			public void handleError(URI uri, HttpMethod httpMethod, @NonNull ClientHttpResponse response)
+					throws IOException {
 				if (!response.getStatusCode().isError()) {
 					return;
 				}
diff --git a/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/api/AnthropicApi.java b/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/api/AnthropicApi.java
index adcb897ad89..24ce1cd14c7 100644
--- a/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/api/AnthropicApi.java
+++ b/models/spring-ai-anthropic/src/main/java/org/springframework/ai/anthropic/api/AnthropicApi.java
@@ -162,7 +162,7 @@ public ResponseEntity<ChatCompletionResponse> chatCompletionEntity(ChatCompletio
 
 		return this.restClient.post()
 			.uri(this.completionsPath)
-			.headers(headers -> headers.addAll(additionalHttpHeader))
+			.headers(headers -> headers.addAll(HttpHeaders.readOnlyHttpHeaders(additionalHttpHeader)))
 			.body(chatRequest)
 			.retrieve()
 			.toEntity(ChatCompletionResponse.class);
@@ -198,7 +198,7 @@ public Flux<ChatCompletionResponse> chatCompletionStream(ChatCompletionRequest c
 
 		return this.webClient.post()
 			.uri(this.completionsPath)
-			.headers(headers -> headers.addAll(additionalHttpHeader))
+			.headers(headers -> headers.addAll(HttpHeaders.readOnlyHttpHeaders(additionalHttpHeader)))
 			.body(Mono.just(chatRequest), ChatCompletionRequest.class)
 			.retrieve()
 			.bodyToFlux(String.class)
diff --git a/models/spring-ai-deepseek/src/main/java/org/springframework/ai/deepseek/api/DeepSeekApi.java b/models/spring-ai-deepseek/src/main/java/org/springframework/ai/deepseek/api/DeepSeekApi.java
index f565c2ba26e..e215f36b23a 100644
--- a/models/spring-ai-deepseek/src/main/java/org/springframework/ai/deepseek/api/DeepSeekApi.java
+++ b/models/spring-ai-deepseek/src/main/java/org/springframework/ai/deepseek/api/DeepSeekApi.java
@@ -94,7 +94,7 @@ public DeepSeekApi(String baseUrl, ApiKey apiKey, MultiValueMap<String, String>
 		Consumer<HttpHeaders> finalHeaders = h -> {
 			h.setBearerAuth(apiKey.getValue());
 			h.setContentType(MediaType.APPLICATION_JSON);
-			h.addAll(headers);
+			h.addAll(HttpHeaders.readOnlyHttpHeaders(headers));
 		};
 		this.restClient = restClientBuilder.baseUrl(baseUrl)
 			.defaultHeaders(finalHeaders)
@@ -153,7 +153,7 @@ public Flux<ChatCompletionChunk> chatCompletionStream(ChatCompletionRequest chat
 
 		return this.webClient.post()
 			.uri(this.getEndpoint(chatRequest))
-			.headers(headers -> headers.addAll(additionalHttpHeader))
+			.headers(headers -> headers.addAll(HttpHeaders.readOnlyHttpHeaders(additionalHttpHeader)))
 			.body(Mono.just(chatRequest), ChatCompletionRequest.class)
 			.retrieve()
 			.bodyToFlux(String.class)
diff --git a/models/spring-ai-huggingface/pom.xml b/models/spring-ai-huggingface/pom.xml
index 9412e970d5d..1d29d73732e 100644
--- a/models/spring-ai-huggingface/pom.xml
+++ b/models/spring-ai-huggingface/pom.xml
@@ -51,7 +51,7 @@
 		<dependency>
 			<groupId>io.swagger.core.v3</groupId>
 			<artifactId>swagger-annotations</artifactId>
-			<version>2.2.15</version>
+			<version>2.2.32</version>
 		</dependency>
 
 		<dependency>
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java
index 2b11927f908..917e966e54e 100644
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiApi.java
@@ -133,7 +133,7 @@ public OpenAiApi(String baseUrl, ApiKey apiKey, MultiValueMap<String, String> he
 			}
 
 			h.setContentType(MediaType.APPLICATION_JSON);
-			h.addAll(headers);
+			h.addAll(HttpHeaders.readOnlyHttpHeaders(headers));
 		};
 		this.restClient = restClientBuilder.clone()
 			.baseUrl(baseUrl)
@@ -181,7 +181,7 @@ public ResponseEntity<ChatCompletion> chatCompletionEntity(ChatCompletionRequest
 
 		return this.restClient.post()
 			.uri(this.completionsPath)
-			.headers(headers -> headers.addAll(additionalHttpHeader))
+			.headers(headers -> headers.addAll(HttpHeaders.readOnlyHttpHeaders(additionalHttpHeader)))
 			.body(chatRequest)
 			.retrieve()
 			.toEntity(ChatCompletion.class);
@@ -215,7 +215,7 @@ public Flux<ChatCompletionChunk> chatCompletionStream(ChatCompletionRequest chat
 
 		return this.webClient.post()
 			.uri(this.completionsPath)
-			.headers(headers -> headers.addAll(additionalHttpHeader))
+			.headers(headers -> headers.addAll(HttpHeaders.readOnlyHttpHeaders(additionalHttpHeader)))
 			.body(Mono.just(chatRequest), ChatCompletionRequest.class)
 			.retrieve()
 			.bodyToFlux(String.class)
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiAudioApi.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiAudioApi.java
index 95604f30075..ecf60d11b54 100644
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiAudioApi.java
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiAudioApi.java
@@ -74,7 +74,7 @@ public OpenAiAudioApi(String baseUrl, ApiKey apiKey, MultiValueMap<String, Strin
 			if (!(apiKey instanceof NoopApiKey)) {
 				h.setBearerAuth(apiKey.getValue());
 			}
-			h.addAll(headers);
+			h.addAll(HttpHeaders.readOnlyHttpHeaders(headers));
 			// h.setContentType(MediaType.APPLICATION_JSON);
 		};
 
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java
index bd32d42d9f6..f013a0b11eb 100644
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiImageApi.java
@@ -27,6 +27,7 @@
 import org.springframework.ai.model.SimpleApiKey;
 import org.springframework.ai.openai.api.common.OpenAiApiConstants;
 import org.springframework.ai.retry.RetryUtils;
+import org.springframework.http.HttpHeaders;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.util.Assert;
@@ -68,7 +69,7 @@ public OpenAiImageApi(String baseUrl, ApiKey apiKey, MultiValueMap<String, Strin
 					h.setBearerAuth(apiKey.getValue());
 				}
 				h.setContentType(MediaType.APPLICATION_JSON);
-				h.addAll(headers);
+				h.addAll(HttpHeaders.readOnlyHttpHeaders(headers));
 			})
 			.defaultStatusHandler(responseErrorHandler)
 			.build();
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java
index b9a6578b636..978d8388c96 100644
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/api/OpenAiModerationApi.java
@@ -27,6 +27,7 @@
 import org.springframework.ai.model.SimpleApiKey;
 import org.springframework.ai.openai.api.common.OpenAiApiConstants;
 import org.springframework.ai.retry.RetryUtils;
+import org.springframework.http.HttpHeaders;
 import org.springframework.http.MediaType;
 import org.springframework.http.ResponseEntity;
 import org.springframework.util.Assert;
@@ -69,7 +70,7 @@ public OpenAiModerationApi(String baseUrl, ApiKey apiKey, MultiValueMap<String,
 				h.setBearerAuth(apiKey.getValue());
 			}
 			h.setContentType(MediaType.APPLICATION_JSON);
-			h.addAll(headers);
+			h.addAll(HttpHeaders.readOnlyHttpHeaders(headers));
 		}).defaultStatusHandler(responseErrorHandler).build();
 	}
 
diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/support/OpenAiResponseHeaderExtractor.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/support/OpenAiResponseHeaderExtractor.java
index 7a4d344755d..d4fd2b979fd 100644
--- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/support/OpenAiResponseHeaderExtractor.java
+++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/metadata/support/OpenAiResponseHeaderExtractor.java
@@ -71,7 +71,7 @@ public static RateLimit extractAiResponseHeaders(ResponseEntity<?> response) {
 
 	private static Duration getHeaderAsDuration(ResponseEntity<?> response, String headerName) {
 		var headers = response.getHeaders();
-		if (headers.containsKey(headerName)) {
+		if (headers.containsHeader(headerName)) {
 			var values = headers.get(headerName);
 			if (!CollectionUtils.isEmpty(values)) {
 				return DurationFormatter.TIME_UNIT.parse(values.get(0));
@@ -82,7 +82,7 @@ private static Duration getHeaderAsDuration(ResponseEntity<?> response, String h
 
 	private static Long getHeaderAsLong(ResponseEntity<?> response, String headerName) {
 		var headers = response.getHeaders();
-		if (headers.containsKey(headerName)) {
+		if (headers.containsHeader(headerName)) {
 			var values = headers.get(headerName);
 			if (!CollectionUtils.isEmpty(values)) {
 				return parseLong(headerName, values.get(0));
diff --git a/pom.xml b/pom.xml
index ca54365aa3a..0c49bb83940 100644
--- a/pom.xml
+++ b/pom.xml
@@ -162,7 +162,7 @@
 		<module>models/spring-ai-azure-openai</module>
 		<module>models/spring-ai-bedrock</module>
 		<module>models/spring-ai-bedrock-converse</module>
-		<module>models/spring-ai-huggingface</module>
+<!--		<module>models/spring-ai-huggingface</module>-->
 		<module>models/spring-ai-minimax</module>
 		<module>models/spring-ai-mistral-ai</module>
 		<module>models/spring-ai-oci-genai</module>
@@ -253,12 +253,12 @@
 		<kotlin.compiler.jvmTarget>${java.version}</kotlin.compiler.jvmTarget>
 
 		<!-- production dependencies -->
-		<spring-boot.version>3.4.5</spring-boot.version>
+		<spring-boot.version>4.0.0-SNAPSHOT</spring-boot.version>
 		<ST4.version>4.3.4</ST4.version>
 		<azure-open-ai-client.version>1.0.0-beta.16</azure-open-ai-client.version>
 		<jtokkit.version>1.1.0</jtokkit.version>
 		<victools.version>4.37.0</victools.version>
-		<kotlin.version>1.9.25</kotlin.version>
+		<kotlin.version>2.1.0</kotlin.version>
 
 		<!-- NOTE: keep bedrockruntime and awssdk versions aligned -->
 		<bedrockruntime.version>2.31.26</bedrockruntime.version>
diff --git a/spring-ai-client-chat/src/main/kotlin/org/springframework/ai/chat/client/ChatClientExtensions.kt b/spring-ai-client-chat/src/main/kotlin/org/springframework/ai/chat/client/ChatClientExtensions.kt
index 40a4c6ffd84..fbebcfae229 100644
--- a/spring-ai-client-chat/src/main/kotlin/org/springframework/ai/chat/client/ChatClientExtensions.kt
+++ b/spring-ai-client-chat/src/main/kotlin/org/springframework/ai/chat/client/ChatClientExtensions.kt
@@ -25,8 +25,8 @@ import org.springframework.core.ParameterizedTypeReference
  * @author Josh Long
  */
 
-inline fun <reified T> ChatClient.CallResponseSpec.entity(): T =
+inline fun <reified T : Any> ChatClient.CallResponseSpec.entity(): T =
 	entity(object : ParameterizedTypeReference<T>() {}) as T
 
-inline fun <reified T> ChatClient.CallResponseSpec.responseEntity(): ResponseEntity<ChatResponse, T> =
-	responseEntity(object : ParameterizedTypeReference<T>() {}) 
+inline fun <reified T : Any> ChatClient.CallResponseSpec.responseEntity(): ResponseEntity<ChatResponse, T> =
+	responseEntity(object : ParameterizedTypeReference<T>() {})
diff --git a/spring-ai-model/src/test/kotlin/org/springframework/ai/tool/resolution/TypeResolverHelperKotlinIT.kt b/spring-ai-model/src/test/kotlin/org/springframework/ai/tool/resolution/TypeResolverHelperKotlinIT.kt
index b7671a89b98..a434f319d94 100644
--- a/spring-ai-model/src/test/kotlin/org/springframework/ai/tool/resolution/TypeResolverHelperKotlinIT.kt
+++ b/spring-ai-model/src/test/kotlin/org/springframework/ai/tool/resolution/TypeResolverHelperKotlinIT.kt
@@ -39,7 +39,7 @@ class TypeResolverHelperKotlinIT {
 		val functionType = TypeResolverHelper.resolveBeanType(this.applicationContext, beanName);
 		val functionInputClass = TypeResolverHelper.getFunctionArgumentType(functionType, 0).rawClass;
 		assertThat(functionInputClass).isNotNull();
-		assertThat(functionInputClass.typeName).isEqualTo(WeatherRequest::class.java.getName());
+		assertThat(functionInputClass!!.typeName).isEqualTo(WeatherRequest::class.java.name)
 	}
 
 	class Outer {
diff --git a/spring-ai-retry/src/main/java/org/springframework/ai/retry/RetryUtils.java b/spring-ai-retry/src/main/java/org/springframework/ai/retry/RetryUtils.java
index 960382d5c96..836dd01a015 100644
--- a/spring-ai-retry/src/main/java/org/springframework/ai/retry/RetryUtils.java
+++ b/spring-ai-retry/src/main/java/org/springframework/ai/retry/RetryUtils.java
@@ -17,12 +17,14 @@
 package org.springframework.ai.retry;
 
 import java.io.IOException;
+import java.net.URI;
 import java.nio.charset.StandardCharsets;
 import java.time.Duration;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import org.springframework.http.HttpMethod;
 import org.springframework.http.client.ClientHttpResponse;
 import org.springframework.lang.NonNull;
 import org.springframework.retry.RetryCallback;
@@ -49,7 +51,7 @@ public boolean hasError(@NonNull ClientHttpResponse response) throws IOException
 		}
 
 		@Override
-		public void handleError(@NonNull ClientHttpResponse response) throws IOException {
+		public void handleError(URI uri, HttpMethod method, @NonNull ClientHttpResponse response) throws IOException {
 			if (response.getStatusCode().isError()) {
 				String error = StreamUtils.copyToString(response.getBody(), StandardCharsets.UTF_8);
 				String message = String.format("%s - %s", response.getStatusCode().value(), error);
diff --git a/vector-stores/spring-ai-elasticsearch-store/src/main/java/org/springframework/ai/vectorstore/elasticsearch/ElasticsearchVectorStore.java b/vector-stores/spring-ai-elasticsearch-store/src/main/java/org/springframework/ai/vectorstore/elasticsearch/ElasticsearchVectorStore.java
index f0919463294..12ca89e7354 100644
--- a/vector-stores/spring-ai-elasticsearch-store/src/main/java/org/springframework/ai/vectorstore/elasticsearch/ElasticsearchVectorStore.java
+++ b/vector-stores/spring-ai-elasticsearch-store/src/main/java/org/springframework/ai/vectorstore/elasticsearch/ElasticsearchVectorStore.java
@@ -24,6 +24,7 @@
 import java.util.stream.Collectors;
 
 import co.elastic.clients.elasticsearch.ElasticsearchClient;
+import co.elastic.clients.elasticsearch._types.mapping.DenseVectorSimilarity;
 import co.elastic.clients.elasticsearch.core.BulkRequest;
 import co.elastic.clients.elasticsearch.core.BulkResponse;
 import co.elastic.clients.elasticsearch.core.SearchResponse;
@@ -331,7 +332,8 @@ private void createIndexMapping() {
 			this.elasticsearchClient.indices()
 				.create(cr -> cr.index(this.options.getIndexName())
 					.mappings(map -> map.properties(this.options.getEmbeddingFieldName(),
-							p -> p.denseVector(dv -> dv.similarity(this.options.getSimilarity().toString())
+							p -> p.denseVector(dv -> dv
+								.similarity(DenseVectorSimilarity.valueOf(this.options.getSimilarity().toString()))
 								.dims(this.options.getDimensions())))));
 		}
 		catch (IOException e) {
